Le défi
C'est assez simple vraiment, trier une liste de nombres.
Détails
Vous devez trier une liste de nombres dans l'ordre croissant, sans utiliser de fonctions de tri / bibliothèques / etc intégrées (c'est- list.sort()
à- dire en Python).
L'entrée / sortie peut être effectuée dans n'importe quelle méthode que vous choisissez, tant qu'elle est lisible par l'homme.
Les failles standard sont toujours interdites.
Le code le plus court en octets gagne.
Vous devez expliquer / lister la méthode de tri que vous avez utilisée (bulle, insertion, sélection, etc.)
L'entrée ne contiendra pas de doublons.
Exemple d'entrée / sortie
Contribution: 99,-2,53,4,67,55,23,43,88,-22,36,45
Sortie: -22,-2,4,23,36,43,45,53,55,67,88,99
Remarque: Un opposé presque direct de Trier une liste de nombres
[7 2 4 1] -> [4 2 3 1]
. De plus, la liste CSV peut-elle être entre crochets? De plus, le format d'entrée spécifique est très approprié pour certaines langues et mauvais pour d'autres. Cela rend l'analyse des entrées importante pour certaines soumissions et inutile pour d'autres.Réponses:
05AB1E , 2 octets
Code:
Même algorithme que la réponse Jelly . Calcule toutes les permutations de l'entrée et sort la plus petite.
Essayez-le en ligne!
Une méthode plus efficace consiste à:
Effectue un tri par sélection . Utilise l' encodage CP-1252 .
Essayez-le en ligne!
la source
Gelée, 3 octets
Cela génère toutes les permutations de la liste d'entrée, puis sélectionne la permutation lexographiquement la plus petite. Très efficace.
Crédits à @Adnan qui a eu la même idée indépendamment.
Essayez-le en ligne!
Gelée, 4 octets
Cela construit la plage du minimum de la liste au maximum de la liste, puis supprime les éléments de la plage non présents dans la liste d'origine. Il s'agit techniquement d'une sorte de seau , avec de très petits seaux. Je ne connais pas de nom pour cette variante spécifique.
Essayez-le en ligne!
Comment ça marche
la source
Python,
4645 octetsTri par sélection simple.
la source
l[:]
pourrait être1*l
Brachylog ,
127 octetsCela utilise le tri par permutation, ce qui est évidemment terrible, mais bon c'est plus court que Pyth!
Explication
la source
Haskell, 38 octets
La fonction binaire
%
insère un nouvel élémenth
dans une liste triéet
en partitionnantt
en un préfixea
d'éléments<h
et un suffixeb
d'éléments>h
, et se colleh
entre eux.L'opération
foldr(%)[]
crée ensuite une liste triée à partir de vide en insérant à plusieurs reprises des éléments de la liste d'entrée.C'est un octet plus court que l'implémentation récursive directe
Une autre stratégie pour 41 octets:
la source
%
comme boucle intérieure d'insertion etfoldr
pour l'appliquer comme boucle extérieure.JavaScript (ES6), 51 octets
Chaque boucle trouve le plus petit nombre qui n'a pas été trouvé jusqu'à présent.
la source
[1,2,3,4,5,4,3,2,1]
produits[1, 2, 3, 4, 5, Infinity, Infinity, Infinity, Infinity]
Python 2, 34 octets
Prend l'entrée comme un ensemble, imprimant ses éléments dans un ordre croissant, se terminant par une erreur.
Une terminaison propre peut être effectuée en 41 octets:
ou
L'entrée peut être considérée comme une liste de 39 octets, ou 38 octets en Python 3.5:
la source
m=min(s)
/s - (m)
comme boucle interne pour rechercher et supprimer le min des éléments non triés, et la récursivité comme externe.Haskell,
424138 octetsBoucle sur tous les entiers (signé 64 bits, sur ma machine) et conserve ceux qui sont dedans
u
. Bien sûr, cela ne se termine pas dans un délai raisonnable.La version précédente a bouclé à travers
[minimum u..maximum u]
laquelle a le même temps d'exécution pire cas.Modifier: @xnor a enregistré un octet. Merci!
la source
filter
est un plus court:f u=filter(`elem`u)[minimum u..maximum u]
[minimum u..]
fonctionne pas pour des raisons de type?f [1,3,0]
, les éléments par défaut sont de typeInteger
non lié, donc le..
ne se termine jamais. Si vous devez l'appeler commef ([1, 3, 0]::[Int])
je suppose, l'annotation de type doit être incluse dans le nombre d'octets.Oracle SQL 11.2, 205 octets
Non golfé
Quant à la méthode de tri, je n'en ai aucune idée,
ORDER BY
je me suis assuré de les oublier.la source
code machine x86-16 (BubbleSort int8_t),
2019 octetscode machine x86-64 / 32 (JumpDownSort)
2119 octetsJournal des modifications:
Merci à @ ped7g pour l' idée
lodsb
/cmp [si],al
, et à mettre cela ensemble avec une augmentation / réinitialisation du pointeur que je regardais. Ne pas avoir besoinal
/ah
permet d'utiliser presque le même code pour les entiers plus grands.Nouvel algorithme (mais lié), de nombreux changements d'implémentation: Bubbly SelectionSort permet une implémentation x86-64 plus petite pour les octets ou les mots-clés; seuil de rentabilité sur x86-16 (octets ou mots). Évite également le bug sur size = 1 que mon BubbleSort a. Voir ci-dessous.
Il s'avère que mon Bubbly Selection Sort avec des swaps chaque fois que vous trouvez un nouveau min est déjà un algorithme connu, JumpDown Sort. Il est mentionné dans Bubble Sort: une analyse algorithmique archéologique (c'est-à-dire comment Bubble Sort est devenu populaire malgré la succion).
Trie les entiers signés 8 bits sur place . (Non signé a la même taille de code, changez simplement le
jge
en ajae
). Les doublons ne sont pas un problème. Nous échangeons en utilisant une rotation de 16 bits par 8 (avec une destination mémoire).Bubble Sort craint pour les performances , mais j'ai lu que c'est l'un des plus petits à implémenter dans le code machine. Cela semble particulièrement vrai lorsqu'il existe des astuces spéciales pour échanger des éléments adjacents. C'est à peu près son seul avantage, mais parfois (dans les systèmes embarqués réels), c'est assez d'avantage pour l'utiliser pour des listes très courtes.
J'ai omis la résiliation anticipée sur aucun échange . J'ai utilisé la boucle BubbleSort «optimisée» de Wikipédia qui évite de regarder les derniers
n − 1
éléments lors de l'exécution pour lan
cinquième fois, donc le compteur de la boucle externe est la limite supérieure de la boucle interne.Liste NASM (
nasm -l /dev/stdout
) ou source simplepush / pop
cx
autour de la boucle interne signifie qu'il s'exécute aveccx
= externe_cx jusqu'à 0.Notez qu'il
rol r/m16, imm8
ne s'agit pas d'une instruction 8086, elle a été ajoutée plus tard (186 ou 286), mais cela n'essaie pas d'être du code 8086, juste du x86 16 bits. Si SSE4.1phminposuw
pouvait aider, je l'utiliserais.Une version 32 bits de ceci (fonctionnant toujours sur des entiers 8 bits mais avec des pointeurs / compteurs 32 bits) est de 20 octets (préfixe de taille d'opérande activé
rol word [esi-1], 8
)Bug: size = 1 est traité comme size = 65536, car rien ne nous empêche d'entrer dans le do / while externe avec cx = 0. (Vous l'utiliseriez normalement
jcxz
pour cela.) Mais heureusement, le tri JumpDown de 19 octets fait 19 octets et n'a pas ce problème.Version originale x86-16 de 20 octets (sans idée de Ped7g). Omis pour économiser de l'espace, consultez l' historique des modifications avec une description.
Performance
Le stockage / rechargement partiellement chevauchant (dans la rotation de destination de la mémoire) provoque un blocage de transfert de magasin sur les processeurs x86 modernes (sauf Atom dans l'ordre). Lorsqu'une valeur élevée se propage vers le haut, cette latence supplémentaire fait partie d'une chaîne de dépendance portée par la boucle. Le stockage / rechargement aspire en premier lieu (comme la latence de transfert de magasin à 5 cycles sur Haswell), mais un blocage de transfert le ramène à plus ou moins 13 cycles. Une exécution dans le désordre aura du mal à le masquer.
Voir aussi: Stack Overflow: bubble sort pour trier la chaîne pour une version de ceci avec une implémentation similaire, mais avec un early-out quand aucun swap n'est nécessaire. Il utilise
xchg al, ah
/mov [si], ax
pour l'échange, qui est de 1 octet de plus et provoque un blocage de registre partiel sur certains processeurs. (Mais cela peut être encore mieux que la rotation de mémoire-dst, qui doit charger à nouveau la valeur). Mon commentaire a quelques suggestions ...Tri JumpDown x86-64 / x86-32, 19 octets (tri int32_t)
Appelable depuis C en utilisant la convention d'appel System V x86-64 as
int bubblyselectionsort_int32(int dummy, int *array, int dummy, unsigned long size);
(valeur de retour = max (tableau [])).Il s'agit de https://en.wikipedia.org/wiki/Selection_sort , mais au lieu de se souvenir de la position de l'élément min, permutez le candidat actuel dans le tableau . Une fois que vous avez trouvé le min (unsorted_region), stockez-le à la fin de la région triée, comme le tri de sélection normal. Cela agrandit la région triée d'une unité. (Dans le code,
rsi
pointe vers un après la fin de la région triée; l'lodsd
avance et ymov [rsi-4], eax
stocke le min.)Le nom Jump Down Sort est utilisé dans Bubble Sort: An Archaeological Algorithmic Analysis . Je suppose que mon tri est vraiment un tri par saut, car les éléments hauts sautent vers le haut, laissant le bas trié, pas la fin.
Cette conception d'échange conduit à la partie non triée du tableau se retrouvant principalement dans un ordre trié inversé, ce qui entraîne de nombreux échanges plus tard. (Parce que vous commencez avec un grand candidat, et continuez à voir des candidats de plus en plus bas, alors vous continuez à permuter.) Je l'ai appelé "pétillant" même s'il déplace les éléments dans l'autre sens. La façon dont il déplace les éléments est également un peu comme un tri par insertion vers l'arrière. Pour le regarder en action, utilisez les GDB
display (int[12])buf
, définissez un point d'arrêt sur l'loop
instruction interne et utilisezc
(continuer). Appuyez sur retour pour répéter. (La commande "display" permet à GDB d'imprimer tout l'état du tableau à chaque fois que nous atteignons le point d'arrêt).xchg
avec mem a unlock
préfixe implicite qui rend cela très lent. Probablement environ un ordre de grandeur plus lent qu'un échange de charge / stockage efficace;xchg m,r
est un par débit 23c sur Skylake, mais charger / stocker / déplacer avec un reg tmp pour un swap efficace (reg, mem) peut décaler un élément par horloge. Cela pourrait être un pire rapport sur un processeur AMD où l'loop
instruction est rapide et ne gênerait pas autant la boucle interne, mais les échecs de branchement seront toujours un gros goulot d'étranglement car les échanges sont courants (et deviennent plus courants à mesure que la région non triée devient plus petite). ).Taille du même code pour
int8_t
: utilisationlodsb
/scasb
,AL
et changer le[rsi/rdi-4]
à-1
. Le même code machine fonctionne en mode 32 bits pour les éléments 8/32 bits. Le mode 16 bits pour les éléments 8/16 bits doit être reconstruit avec les décalages modifiés (et les modes d'adressage 16 bits utilisent un codage différent). Mais toujours 19 octets pour tous.Il évite l'initiale
dec ecx
en comparant avec l'élément qu'il vient de charger avant de continuer. Lors de la dernière itération de la boucle externe, il charge le dernier élément, vérifie s'il est inférieur à lui-même, puis c'est fait. Cela lui permet de fonctionner avec size = 1, où mon BubbleSort échoue (le traite comme size = 65536).J'ai testé cette version (en GDB) en utilisant cet appelant: Essayez-le en ligne! . Vous pouvez l'exécuter sur TIO, mais bien sûr sans débogueur ni impression. Pourtant, celui
_start
qui l'appelle quitte avec exit-status = le plus grand élément = 99, donc vous pouvez voir que cela fonctionne.la source
cx
et utiliserloop
pour les deux? Peut-être boucler dans l'autre sens, de l'arrière vers l'avant du tableau afin que nous comptions un index jusqu'à zéro? (Et incrémentezbx
parce que la partie triée est à la fin vers laquelle vous bouclez).sub si, cx
de faire partie de la boucle externe en utilisant un pointeur au lieu de l'indexation, mais je n'avais pas pensé àlodsb
/cmp [si], al
. J'envisageaislodsw
/dec si
, oulodsb
/xchg al,ah
de toujours m'installercmp ah,al
cld
, ou je suppose que nous pourrions faire cette partie de la convention d'appel. AFAIK, après avoirDF
effacé n'est pas une partie standard des conventions d'appel 16 bits, seulement 32/64. Ou est-ce juste que vous ne pouvez pas l'assumer dans un chargeur de démarrage? Mais avec une convention d'appel de registre personnalisé, c'est autant un fragment de code qu'une fonction, alors bien sûr, pourquoi ne pas exiger DF = 0. (Et si nous voulons, ES = DS pour que nous puissionsscasb
au lieu delodsb
si c'est plus pratique.)C, 72 octets
Bubblesort. Le premier argument est un pointeur sur le tableau, le deuxième argument est la longueur du tableau. Fonctionne avec gcc.
la source
MATL ,
1110 octetsExamen extrêmement inefficace de toutes les permutations de l'entrée.
Essayez-le en ligne!
Explication
la source
Rubis, 40 octets
Tri par sélection. Fonction anonyme; prend la liste en argument.
la source
Python, 120 octets
Ce ne sera probablement pas la réponse la plus courte mais j'ai l'impression que cet algorithme appartient ici. appeler avec une liste d'entiers, ils seront imprimés de manière triée sur stdout. Je ne l'essayerais cependant pas avec un trop grand nombre.
la source
MIPS, 68 octets
Il y a quelque temps, j'ai écrit une simple implémentation de tri à bulle non optimisée. Le décompte d'octets commence à
loop
et se termine àli $v0, 10
, en supposant que l'adresse et la longueur de la liste sont déjà en mémoire.Maintenant j'attends d'être soufflé hors de l'eau avec x86 ...
la source
swapped=true
vérification anticipée et le compte à rebours en fonction de la taille du tableau. Voir ma version x86-16 de 20 octets qui trie les entiers 8 bits . Je pourrais faire une version x86 normale 32 ou 64 bits qui trie les entiers 32 bits à un moment donné, mais les entiers 8 bits en mode 16 bits sont une sorte de point idéal pour x86.Awk, 66 octets
Les tableaux dans awk sont comme des dictionnaires, pas comme des tableaux C. Les index peuvent être non contigus et ils augmentent (et sont créés) selon les besoins. Ainsi, nous créons un tableau
a
pour l'entrée, chaque ligne étant une clé. Et nous enregistrons les valeurs min et max. Ensuite, nous bouclons de min à max et imprimons toutes les clés qui existent dansa
.b
est juste pour éviter une utilisation répétée de$0
.la source
Python 3,
916247 octetsMerci à wnnmaw et Seeq pour leur aide au golf.
L'argument
z
devrait être une liste. Il s'agit d'une variante du tri par sélection.Je ne sais pas comment se
min
compare à celabuilt-in sorting functions
, car je ne sais pas comment Python implémentemin
. Espérons que cette solution est toujours valable. Toutes les suggestions de golf dans les commentaires ou dans chat PPCG sont les bienvenues.la source
def f(z):\nwhile z:m=min(z);z.remove(m);yield m
MATL , 11 octets
Essayez-le en ligne!
Cela trie par la procédure suivante, qui est O ( n 2 ):
MATL est basé sur la pile. Le tableau avec les valeurs restantes est conservé en haut de la pile. Les valeurs supprimées sont ci-dessous, dans l'ordre. À la fin du programme, toutes ces valeurs sont affichées. Le tableau en haut serait également affiché, mais comme il est vide, il ne s'affiche pas.
la source
Pyth -
15131110 octetsDeux octets enregistrés grâce à @Jakube.
Bogosort.
Essayez-le en ligne ici .
Je n'ai pas besoin du
h
cuz nous sommes garantis sans doublons.la source
Sérieusement, 6 octets
Essayez-le en ligne!
Cela fait la même chose que de nombreuses autres réponses: générer toutes les permutations, sélectionner minimum. J'ai un peu oublié que cela fonctionnerait pendant que je travaillais sur la solution ci-dessous.
Explication:
Sérieusement, 25 octets (non concurrents)
Ce serait compétitif s'il n'y avait pas un bug dans la commande de lecture aléatoire que je viens de corriger.
Essayez-le en ligne! Cela implémente le meilleur algorithme de tri jamais créé : Bogosort !
Explication:
la source
MATL,
1716 octetsEnregistrement d'un octet créant un tableau nul grâce à @LuisMendo
Tri par seau. Ne l'essayez pas avec une plage supérieure à 2 31 -1.
Essayez-le en ligne!
Explication
TIL:
[]
et l'agrandir, comme dans MATLAB(
pour l'indexation des affectationsM
presse-papiers automatiqueNouveau jour, nouveau TIL:
vertcat
crée comme par magie un tableau vide quand il n'y a rien sur la pile pour concaténerla source
[]
peut être remplacée parv
. En effet, le nombre d'entrées par défaut dev
est le nombre d'éléments de la pilevertcat(STACK{:})
Julia,
2827 octetsEssayez-le en ligne!
la source
R, 68 octets
Prend les entrées
i
et sortieso
qui est la liste triée.Explication:
Éviter les permutations signifie qu'il peut trier de grandes listes relativement rapidement. L'astuce est que la soustraction de la plus petite valeur de l'entrée laisse un seul 0 qui détermine à la fois la plus petite valeur et la position de la plus petite valeur.
la source
Java 8,
11292 octetsVoici un autre type de sélection. L'entrée est un nombre
List t
entier et la sortie triée est imprimée en sortie standard.Mise à jour
la source
t
existe, ce qui en fait un extrait; nous exigeons que les soumissions soient des programmes ou des fonctions complets qui utilisent nos formats d'E / S par défaut . Nous demandons également aux importations de prendre en compte le nombre d'octets. Faites moi savoir si vous avez des questions!Rétine, 95
Tri des bulles modifié. Je soupçonne qu'il existe de bien meilleures façons de le faire, même sans le tri rétinien intégré.
n
comme chiffre; laissez tomber les-
signes.1
comme chiffre; ajouter1
à chacun, de sorte que zéro est représenté par1
.Essayez-le en ligne.
la source
Rubis, 22 octets
Une sorte de permutation rapide . Fonctionne dans l'espace et le temps O (n!).
la source
Clojure,
7335 octetsBogosort :)
Version précédente:
Réduit à une liste triée
r
en la divisant en parties "plus petites que i" et "plus grandes que i". Je suppose que c'est le type d'insertion .la source
recur
utiliser une fonction anonyme. Je ne savais pas non plusshuffle
.Rubis,
2624 octetsTri de sélection, similaire à la réponse de Value Ink, mais utilisant une approche différente pour une plus grande absence de golf.
Selon la spécification: "L'entrée / sortie peut être effectuée dans n'importe quelle méthode que vous choisissez, tant qu'elle est lisible par l'homme". Je pense que cela correspond à la description, la sortie est un tableau de tableaux avec un seul élément.
Exemple:
la source
Java 7,
106104 octetsVoici un bon tri de bulles oléiques. Le paramètre de fonction est modifié sur place, donc je n'ai rien à retourner. J'essaie toujours d'en extraire quelques octets pour que je puisse battre la lambda java que quelqu'un a publiée.
-1 octet merci à Geobits pour avoir souligné que le swapping normal bat xor'ing
-1 octet merci à Leaky Nun pour avoir souligné que je peux déplacer toutes les déclarations int dans la boucle for
Essayez-le en ligne!
la source
Rubis, 22 octets
Construit un tableau hors de la plage entre les éléments minimum et maximum du tableau d'entrée. Renvoie l'intersection entre les deux tableaux.
la source