L'étrange machine à trier à des fins néfastes

18

Bons golfeurs!

Votre défi consiste à supprimer complètement une série de chiffres.

Contribution

Exactement 100 entiers seront introduits dans votre programme. Votre programme peut accepter l'entrée soit sous forme de fichier, soit via stdin. Chaque entier sera séparé par un caractère de nouvelle ligne.

Ces 100 entiers vont de la valeur minimale à la valeur maximale d'un entier signé dans la langue de votre choix.

Il n'y aura pas de valeurs en double. Les valeurs peuvent être ordonnées, non ordonnées ou partiellement ordonnées - votre programme devrait être capable de gérer chaque cas.

Production

La sortie doit être chacun des 100 entiers, complètement non triés, chacun séparé par un caractère de nouvelle ligne. La sortie peut être via stdout ou vers un fichier.

Complètement non trié signifie qu'aucune valeur n'est adjacente à une valeur à laquelle elle serait adjacente si la liste était complètement triée dans une séquence ordonnée.

But

1 point par personnage et le score le plus bas l'emporte. Il y a un bonus de -100 pour toute solution n'utilisant aucune fonction de tri intégrée ou de bibliothèque. Il y a un bonus de -20 pour toutes les solutions n'utilisant pas de fonctions de nombres aléatoires intégrées.

J'ai essayé de définir cette question aussi complètement que possible. Si vous avez des questions, n'hésitez pas à demander. Si vous avez des commentaires sur la façon dont je pourrais faire mieux la prochaine fois, faites-le moi savoir.

Fore!

lochok
la source
Il y a exactement 100 entiers en entrée, et il n'y a pas de valeurs en double (voir sous "Entrée")
lochok
C'est vrai, je n'ai pas remarqué ça.
Strigoides
2
Ce n'est pas un doublon en tant que tel, mais ce n'est pas très différent de codegolf.stackexchange.com/questions/6487/…
Peter Taylor
Tant de réponses intelligentes! Je sélectionnerai la réponse la plus courte le 31 octobre à 8 h 10-Zoulou
lochok

Réponses:

9

GolfScript (score 27-120 = -93)

~].,{{.2$<{\}*}*]}*.(;+2%n*

Remarque: cela $fait référence à un élément de la pile. Il y a un tri, mais cela se fait avec un tri à bulles codé manuellement.

Merci à Howard pour -90 => -92; et Ilmari, qui a inspiré -92 => -93.

Peter Taylor
la source
Créditez une réponse aussi concise, mais (pardonnez-moi, car je ne parle pas ou ne comprends pas GolfScript) - le ^ ne le disqualifierait-il pas du bonus de -100?
lochok
1
@lochok, la fonction de tri intégrée est $- c'est pourquoi j'ai mentionné que $le programme n'est pas un tri (il dépend du contexte). La majorité du programme (28 des 42 caractères) définit la fonction ^; la première version, utilisant le tri intégré, ne comportait que 14 caractères.
Peter Taylor
Ahh - c'est vrai. Merci pour la clarification!
lochok
1
Vous pouvez enregistrer deux caractères avec la boucle de sortie suivante: 2/{~p}%n*.
Howard
1
2/zip~+n*et .);\+2%n*faites aussi l'affaire pour le même nombre de caractères que la version de @ Howard. Hélas, je n'ai pas encore réussi à trouver quelque chose de plus court.
Ilmari Karonen du
6

Python -26

(94-120): Nouvelle approche grossière. Continuez à insérer les éléments les plus bas dans une nouvelle liste pour obtenir le tri des éléments, puis répétez:

t=l=[]
i=N=100
exec't=t+[input()];'*N+'l+=[t.pop(t.index(min(t)))];'*N+'print l[i%N];i+=3;'*N

Python -13

(107-120): Première approche: supprime les quatre éléments les plus bas à la fois, puis imprimez ces quatre dans un autre ordre:

exec'l=[]'+'+[input()]'*100
while l:
 a,b,c,d=eval('l.pop(l.index(min(l))),'*4)
 for e in[b,d,a,c]:print e
daniero
la source
t=l=[]et vous exec't+=[input()];'*100ferait économiser quelques caractères
quasimodo
vous pouvez également utiliser une execinstruction pour plusieurs boucles.
quasimodo
@quasimodo J'ai essayé quelque chose comme ça, mais avec t=l=[]t et l pointe vers le même objet et ça ne marche pas. Sauter les parenthèses execest bien cependant.
daniero
Vous pouvez utiliser t=t+[input()];, cela crée un nouvel objet à chaque fois. Et vous pouvez même faire la boucle d'impression dans l'instruction exec: ';i+=1;print l[i*3%100]'*100.
quasimodo
Tu as encore raison. Merci! Ajout d'un autre golf comme supprimer %3et éviter la répétition de 100.
daniero
4

C: 11 (131-120)

Le programme lit à partir de stdin et effectue un simple tri par insertion, après quoi il imprime le nième avec le numéro n + 50e, comme la plupart des autres solutions.

main(){int*i,a[101],*j=a;while(scanf("%d",a)>0)for(i=++j;i-->a;)i[1]=*i>=*a?*i:*(i=a);while(a<(i=j-50))printf("%d\n%d\n",*i,*j--);}
quasimodo
la source
3

Mathematica -56 44 4 (95-120) = -25

Éditer :

Cette version ne s'appuie ni sur des fonctions intégrées pour le tri des listes, ni sur des fonctions de randomisation.

Riffle[RotateLeft[#[[All, 2]], 2], #[[All, 1]]] &
[Partition[l //. {x___, a_, b_, y___} /; b < a :> {x, b, a, y}, 2]]
DavidC
la source
N'est-ce Sortpas une fonction de tri intégrée?
Peter Taylor
Vous avez raison! J'ai manqué la contrainte du tri.
DavidC
J'ai fait un tri roulé à la main.
DavidC
3

J, -63 (57-120) caractères

Puisque tout le monde suit la voie de tri auto-écrite ...

,50(}.,.{.)($:@([-.m),~m=.]#~]=<./)^:(0<#),".[;._2[1!:1[3

N'utilise aucune fonction de nombre aléatoire, ni aucun tri intégré.

Utilise un tri par sélection récursive simple pour trier l'entrée.

Gareth
la source
3

Rubis 1.9, -59

(61-120)

Récursivité! Celui-ci en fait, contrairement à mes précédentes tentatives Ruby, ne trie pas la liste indépendamment de leur ordre d'origine.

p *(f=->l{l[1]&&f[l-m=l.minmax]+m||[]})[$<.map &:to_i].rotate

Tentatives précédentes

Mignon à une ligne, utilisant maintenant le tri intégré pour fonctionner correctement:

$<.map(&:to_i).sort.each_slice(4){|a,b,c,d|p b,d,a,c}

Première - N'a pas nécessairement dénaturé les 4 dernières valeurs:

l=$<.map &:to_i
48.times{l-=p *l.minmax}
a,b,c,d=l
p b,d,a,c
daniero
la source
1
Votre solution -72 suppose que la liste commence triée, ce qui n'est pas le cas.
histocrate
Oups. Il semble que je n'ai pas relu la question à fond lorsque j'ai revu celle-ci. Va essayer de trouver autre chose.
daniero
@histocrate qui devrait le faire.
daniero
1

Python 2: 90 caractères

n=100
s=sorted(int(raw_input())for i in range(n))
for i in range(n):print s[(4*i+4*i/n)%n]

tentative paresseuse mais juste pour commencer

miles
la source
1

Python 48 = (148 - 100)

from random import*
x=[input()for i in range(100)]
while any(abs(x[i]-x[i+1])>1 for i in range(99)):n=randint(1,99);x=x[n:]+x[:n]
for j in x:print j

Je n'ai pas testé cela car il n'est pas garanti (ou probable) de fonctionner dans un laps de temps raisonnable, mais devrait fonctionner en théorie avec un temps infini.

scleaver
la source
1
x=map(input,['']*100)
ugoren
Et je ne pense pas que vous ayez même besoin des []s supplémentaires , juste d'une chaîne de caractères unique.
job
1

Python 27 (147 - 100 - 20)

R=range
def S(L):
 for i in R(len(L)-1):
    if L[i]>L[i+1]:L[i:i+2]=[L[i+1],L[i]];S(L)
a=map(input,['']*100);S(a)
for i in R(100):print a[i/2+i%2*50]

Remarque: les espaces avant if L[i]>...doivent être un onglet mais apparemment apparaître comme des espaces dans un bloc de code.

Mat
la source
Avec, R=rangevous pouvez enregistrer 5 caractères.
scleaver
a=map(input,['']*100)
ugoren
1

Perl 5: 95 - 120 = -25 caractères

Compter la ligne de commande suivante:

perl -ne '$n=$_;splice@n,(grep{$n[$_]>$n}0..@n),0,$n}{print for map{@n[$_,$#n/2+$_+1]}0..$#n/2'
Matthias
la source
1

Rubis: -50 (70 caractères - 120)

J'ai fait la même chose que beaucoup d'autres réponses: supprimez de manière itérative le max et le min de la liste d'entrée et ajoutez-les à la sortie. Cependant, j'ai réalisé que si les 2 nombres de chaque côté de la médiane sont eux-mêmes consécutifs, la sortie sera incorrecte (car ces 2 nombres consécutifs apparaîtront ensemble à la fin de la sortie). Pour résoudre ce problème, je fais pivoter la liste "non triée" de 1 élément vers la droite:

n=$*.map &:to_i;u=[];50.times{u+=n.minmax;n-=u.last 2};p *u.rotate(-1)

Ou, pour utiliser arbitrairement de nombreuses entrées (en utilisant seulement 4 caractères supplémentaires):

n=$*.map &:to_i;u=[];(u+=n.minmax;n-=u.last 2)while n.any?;p *u.rotate(-1)

Remarque: Certaines réponses Ruby de moins de caractères ont déjà été publiées, mais ces solutions n'ont pas résolu le problème médian (et / ou supposé une liste d'entrée triée).

Jonathan Hefner
la source
1

J 37-100 = -63

({~?~@#)^:(+./@(1=|)@(2&(-/\))@/:)^:_

N'utilise aucun tri (mais utilise le classement) Utilise des nombres aléatoires.

Explication:

({~?~@#)             NB. Randomizes the array
^: foobar ^:_        NB. as long as
foo =: +./@(1 = |)   NB. as any 1 == absolute value of
bar =: (2&(-/\))@/:  NB. differences between adjacent ranks
foobar =: foo@bar
jpjacobs
la source
1

Brachylog , 22 octets - 120 = -98

ṇịᵐpX¬{p≤₁s₂.&s₂p}∧Xẉᵐ

Essayez-le en ligne!

La liaison TIO n'a qu'une entrée de huit entiers, au lieu de cent, car elle est si terriblement lente qu'elle ne peut plus gérer en 60 secondes. La raison en est que, entre autres choses, plutôt que d'implémenter un algorithme de tri simple mais normal pour le bonus obligatoire, j'ai utilisé par souci de concision ce qui équivaut à un bogosort déterministe:p≤₁ arrière à travers chaque permutation de l'entrée jusqu'à ce qu'il en trouve une ce qui n'est pas décroissant. Bien qu'une raison plus importante serait probablement qu'il utilise un degré similaire de force brute pour trouver la sortie, et qu'il recalcule la version triée à chaque fois ... J'ai essayé de le tester sur une entrée réelle de taille 100, mais je suis Je ne sais pas combien de jours cela prendra.

Une meilleure version globale:

Brachylog , 14 octets - 20 = -6

p.¬{os₂.&s₂p}∧

Essayez-le en ligne!

Cela ignore les exigences d'E / S archaïques pour la brièveté et néglige de prendre le bonus de -100 afin qu'il puisse éventuellement être testé sans superordinateur (bien qu'au moment de la rédaction de ce document, je ne l'ai exécuté que sur 20 éléments pendant plusieurs minutes et il ne m'a toujours rien donné).

 .                The output is
p                 a permutation of
                  the input
  ¬{        }∧    such that it cannot be proven that
         s₂       a pair of adjacent values in
        &         the output
       .   p      is a permutation of
     s₂           a pair of adjacent values in
    o             the output sorted.
Chaîne indépendante
la source
Bien que ce ne soit pas exactement une réponse pratique, cela pourrait être utile pour valider la sortie d'autres programmes, car la plupart d'entre eux ne font que décrire la contrainte placée sur la sortie.
Unrelated String
0

Forth (gforth) , 79-120 = -21 octets

: f 100 0 do dup i 2 mod 4 * 2 - i + i 99 = i 0 = - 3 * + cells + @ . cr loop ;

Essayez-le en ligne!

Ignorez les exigences d'entrée désuètes et prend l'entrée comme une adresse en mémoire où les numéros sont stockés.

Explication

Boucle sur tous les nombres de 0 à 99. Pour chaque nombre (n):

  • Si n est 0:
    • afficher la valeur à l'adresse du tableau + 1
  • Sinon, si n est 99:
    • sortie la valeur à l'adresse du tableau + 98
  • Sinon, si n est impair:
    • afficher la valeur à l'adresse du tableau + (n + 2)
  • Sinon (n est pair):

    • afficher la valeur à l'adresse du tableau + (n - 2)
  • Sortie d'une nouvelle ligne

Explication du code

: f               \ start new word definition
  100 0 do        \ loop from 0 to 99
    dup           \ duplicate the array address
    i             \ place the loop index on the stack
    2 mod 4 * 2 - \ convert to 2 if it's odd and -2 if it's even
    i +           \ add the result to the the loop index
    i 99 =        \ if i = 99 place -1 on top of the stack, else place a 0
    i 0 =         \ i i = 0 place -1 on top of the stack, else place 0
    - 3 *         \ subtract previous two results from each other and multiply by 3
\ the above line is used to avoid writing if/then by instead using math to get 98 and 1
    +             \ add result to existing result from above
    cells         \ multiply by the size of a single integer in memory
    +             \ add to the array's starting address
    @ . cr        \ get the value at the calculated address, print it, then print a newline
  loop            \ end the loop
;                 \ end the word definition
reffu
la source