Die Herausforderung
Es ist wirklich ganz einfach, eine Liste von Zahlen zu sortieren.
Einzelheiten
Sie müssen eine Liste mit Zahlen in aufsteigender Reihenfolge sortieren, ohne die integrierten Sortierfunktionen / libraries / etc (dh list.sort()
in Python) zu verwenden.
Die Ein- / Ausgabe kann in jeder von Ihnen gewählten Methode erfolgen, sofern dies für den Menschen lesbar ist.
Standardlücken sind wie immer verboten.
Kürzester Code in Bytes gewinnt.
Sie müssen erklären / auflisten, welche Sortiermethode Sie verwendet haben (Blase, Einfügung, Auswahl usw.)
Die Eingabe enthält keine Duplikate.
Sample Input / Output
Eingang: 99,-2,53,4,67,55,23,43,88,-22,36,45
Ausgabe: -22,-2,4,23,36,43,45,53,55,67,88,99
Hinweis: Nahezu genau das Gegenteil von Liste mit Zahlen sortieren
[7 2 4 1] -> [4 2 3 1]
. Kann sich die CSV-Liste auch in eckigen Klammern befinden? Das spezielle Eingabeformat eignet sich auch sehr gut für einige Sprachen und schlecht für andere. Dadurch wird das Parsen von Eingaben für einige Übermittlungen zu einem großen Teil und für andere zu einem unnötigen Teil.Antworten:
05AB1E , 2 Bytes
Code:
Gleicher Algorithmus wie die Jelly-Antwort . Berechnet alle Permutationen der Eingabe und gibt die kleinste aus.
Probieren Sie es online!
Eine effizientere Methode ist:
Führt eine Auswahlsortierung durch . Verwendet die CP-1252- Codierung.
Probieren Sie es online!
quelle
Gelee, 3 Bytes
Dies generiert alle Permutationen der Eingabeliste und wählt dann die lexographisch kleinste Permutation aus. Sehr effizient
Dank an @Adnan, der selbständig die gleiche Idee hatte.
Probieren Sie es online!
Gelee, 4 Bytes
Dadurch wird der Bereich vom Minimum der Liste bis zum Maximum der Liste erstellt. Anschließend werden die in der ursprünglichen Liste nicht vorhandenen Bereichselemente verworfen. Dies ist technisch eine Eimersorte mit sehr kleinen Eimern. Mir ist kein Name für diese bestimmte Variante bekannt.
Probieren Sie es online!
Wie es funktioniert
quelle
Python,
4645 BytesEinfache Auswahlsortierung.
quelle
l[:]
könnte sein1*l
Brachylog ,
127 BytesDies verwendet die Permutationssorte, die offensichtlich schrecklich ist, aber hey, sie ist kürzer als Pyth!
Erläuterung
quelle
Haskell, 38 Bytes
Die Binärfunktion
%
fügt ein neues Elementh
in eine sortierte Liste ein,t
indem sie est
in ein Präfixa
von Elementen<h
und ein Suffixb
von Elementen unterteilt>h
undh
dazwischen einfügt.Die Operation erstellt
foldr(%)[]
dann eine sortierte Liste aus leeren Elementen, indem wiederholt Elemente aus der Eingabeliste eingefügt werden.Dies ist ein Byte kürzer als die direkte rekursive Implementierung
Eine andere Strategie für 41 Bytes:
quelle
%
als Einfügung innere Schleife undfoldr
als äußere Schleife anzuwenden.JavaScript (ES6), 51 Byte
Jede Schleife findet die kleinste Nummer, die noch nicht gefunden wurde.
quelle
[1,2,3,4,5,4,3,2,1]
entsteht[1, 2, 3, 4, 5, Infinity, Infinity, Infinity, Infinity]
Python 2, 34 Bytes
Nimmt die Eingabe als Gruppe, druckt die Elemente in aufsteigender Reihenfolge und endet mit einem Fehler.
Eine saubere Beendigung kann in 41 Bytes erfolgen:
oder
Die Eingabe kann als Liste für 39 Bytes oder 38 Bytes in Python 3.5 erfolgen:
quelle
m=min(s)
/s - (m)
als innere Schleife verwendet, um die Min-Werte der unsortierten Elemente zu ermitteln und zu entfernen, und die Rekursion als äußere.Haskell,
424138 BytesDurchläuft alle Ganzzahlen (64-Bit mit Vorzeichen auf meinem Computer) und behält diejenigen bei, die sich in befinden
u
. Natürlich ist es nicht in angemessener Zeit fertig.Die vorherige Version durchlief
[minimum u..maximum u]
die gleiche Worst-Case-Laufzeit.Edit: @xnor hat ein Byte gespeichert. Vielen Dank!
quelle
filter
ist eine kürzer:f u=filter(`elem`u)[minimum u..maximum u]
[minimum u..]
nicht?f [1,3,0]
, beim Aufrufen geben die Elemente standardmäßigInteger
ungebunden ein, sodass das..
nie endet. Wenn Sie es so nennen müssenf ([1, 3, 0]::[Int])
, muss die Typanmerkung in die Byteanzahl einbezogen werden.Oracle SQL 11.2, 205 Byte
Nicht golfen
Was für eine Art Methode es ist, ich habe keine Ahnung,
ORDER BY
stellte sicher , dass ich sie vergessen habe.quelle
x86-16-Maschinencode (BubbleSort int8_t),
20 bis19 Bytex86-64 / 32-Maschinencode (JumpDownSort)
2119 BytesÄnderungsprotokoll:
Vielen Dank an @ ped7g für die
lodsb
/cmp [si],al
-Idee und das Zusammenfügen mit einem Zeigerinkrement / -Reset, das ich mir angesehen habe. Wir brauchen nichtal
/ah
lassen uns fast den gleichen Code für größere ganze Zahlen verwenden.Neuer (aber verwandter) Algorithmus, viele Implementierungsänderungen: Bubbly SelectionSort ermöglicht eine kleinere x86-64-Implementierung für Bytes oder Dwords; Break-Even auf x86-16 (Bytes oder Wörter). Vermeidet auch den Fehler bei Größe = 1, den mein BubbleSort hat. Siehe unten.
Es stellt sich heraus, dass meine Bubbly Selection Sort mit Swaps jedes Mal, wenn Sie eine neue Min finden, bereits ein bekannter Algorithmus ist, JumpDown Sort. Es wird in Bubble Sort: Eine archäologische algorithmische Analyse erwähnt (dh wie Bubble Sort trotz Saugen populär wurde).
Sortiert 8-Bit-Ganzzahlen mit Vorzeichen direkt . (Unsigned hat die gleiche Codegröße, ändern Sie einfach die
jge
in ajae
). Duplikate sind kein Problem. Wir tauschen mit einer 16-Bit-Drehung um 8 (mit einem Speicherziel).Bubble Sort ist der Hammer für die Leistung , aber ich habe gelesen, dass es eines der kleinsten ist, das in Maschinencode implementiert werden kann. Dies scheint insbesondere dann der Fall zu sein, wenn es spezielle Tricks zum Austauschen benachbarter Elemente gibt. Dies ist so ziemlich der einzige Vorteil, aber manchmal (in realen eingebetteten Systemen) reicht dieser Vorteil aus, um ihn für sehr kurze Listen zu verwenden.
Ich habe die vorzeitige Kündigung für keine Swaps ausgelassen . Ich habe die "optimierte" BubbleSort-Schleife von Wikipedia verwendet, die es vermeidet, die letzten
n − 1
Elemente zu betrachten, wenn sie zumn
-ten Mal ausgeführt werden, sodass der Zähler der äußeren Schleife die Obergrenze für die innere Schleife ist.NASM-Auflistung (
nasm -l /dev/stdout
) oder einfache Quellepush / pop von
cx
um die innere Schleife herum bedeutet, dass sie mitcx
= outer_cx bis auf 0 läuft .Beachten Sie, dass
rol r/m16, imm8
es sich nicht um einen 8086-Befehl handelt, der später hinzugefügt wurde (186 oder 286), aber es wird nicht versucht, 8086-Code zu sein, sondern nur 16-Bit x86. Wenn SSE4.1phminposuw
helfen würde, würde ich es verwenden.Eine 32-Bit-Version davon (die immer noch mit 8-Bit-Ganzzahlen, aber mit 32-Bit-Zeigern / Zählern arbeitet) hat eine Größe von 20 Byte (Präfix für Operandengröße aktiviert
rol word [esi-1], 8
).Bug: size = 1 wird als size = 65536 behandelt, weil nichts uns davon abhält, das äußere do / while mit cx = 0 zu betreten. (Sie würden normalerweise dafür verwenden
jcxz
.) Aber zum Glück ist die 19-Byte-JumpDown-Sortierung 19 Byte und hat dieses Problem nicht.Original x86-16 20-Byte-Version (ohne die Idee von Ped7g). Aus Platzgründen ausgelassen, finden Sie im Bearbeitungsverlauf eine Beschreibung.
Performance
Teilweise überlappendes Speichern / Neuladen (beim Rotieren des Speicherziels) führt bei modernen x86-CPUs (außer Atom in der richtigen Reihenfolge) zu einem Stillstand der Speicherweiterleitung. Wenn ein hoher Wert nach oben sprudelt, ist diese zusätzliche Latenzzeit Teil einer durch eine Schleife übertragenen Abhängigkeitskette. Das Speichern / Neuladen ist an erster Stelle scheiße (wie die Speicherweiterleitungsverzögerung von 5 Zyklen bei Haswell), aber ein Weiterleitungsstopp bringt es auf mehr als 13 Zyklen. Bei der Ausführung außerhalb der Reihenfolge kann dies nur schwer ausgeblendet werden.
Siehe auch: Stapelüberlauf: Blasensortierung zum Sortieren von Zeichenfolgen für eine Version mit einer ähnlichen Implementierung, jedoch mit einem frühen Aus, wenn keine Auslagerungen erforderlich sind. Es verwendet
xchg al, ah
/mov [si], ax
zum Austauschen, was 1 Byte länger ist und bei einigen CPUs einen Teilregister-Stillstand verursacht. (Aber es kann immer noch besser sein, als den Speicher zu drehen, der den Wert erneut laden muss). Mein Kommentar dort hat einige Vorschläge ...x86-64 / x86-32 JumpDown-Sortierung, 19 Byte (sortiert nach int32_t)
Aufrufbar von C unter Verwendung der x86-64-System-V-Aufrufkonvention als
int bubblyselectionsort_int32(int dummy, int *array, int dummy, unsigned long size);
(Rückgabewert = max (array [])).Dies ist https://en.wikipedia.org/wiki/Selection_sort , aber anstatt sich an die Position des Elements min zu erinnern, tauschen Sie den aktuellen Kandidaten in das Array . Wenn Sie die minimale (unsortierte_Region) gefunden haben, speichern Sie sie wie bei der normalen Auswahlsortierung am Ende der sortierten Region. Dies vergrößert den sortierten Bereich um eins. (Zeigen Sie im Code
rsi
auf eins nach dem Ende des sortierten Bereichs,lodsd
schieben Sie ihn vor undmov [rsi-4], eax
speichern Sie die Min zurück.)Der Name Jump Down Sort wird in Bubble Sort: An Archaeological Algorithmic Analysis verwendet . Ich denke, meine Sortierung ist wirklich eine Jump Up-Sortierung, da hohe Elemente nach oben springen und den unteren Teil sortiert lassen, nicht das Ende.
Dieses Austauschdesign führt dazu, dass der unsortierte Teil des Arrays größtenteils in umgekehrter Reihenfolge abläuft, was später zu vielen Auslagerungen führt. (Da Sie mit einem großen Kandidaten beginnen und immer niedrigere Kandidaten sehen, tauschen Sie weiter.) Ich habe es "sprudelnd" genannt, obwohl es Elemente in die andere Richtung bewegt. Die Art und Weise, wie Elemente verschoben werden, ist auch ein bisschen wie beim Einfügen in Rückwärtsrichtung. Um es in Aktion zu sehen, verwenden Sie GDBs
display (int[12])buf
, setzen Sie einen Haltepunkt für die innereloop
Anweisung und verwenden Siec
(continue). Drücken Sie die Eingabetaste, um den Vorgang zu wiederholen. (Der Befehl "display" veranlasst GDB, jedes Mal, wenn wir den Haltepunkt erreichen, den gesamten Array-Status zu drucken.)xchg
with mem hat ein impliziteslock
Präfix, das dies besonders langsam macht. Vermutlich um eine Größenordnung langsamer als ein effizienter Load / Store-Swap;xchg m,r
beträgt eins pro 23c Durchsatz bei Skylake, aber Laden / Speichern / Verschieben mit einem tmp-Register für einen effizienten Tausch (reg, mem) kann ein Element pro Takt verschieben. Auf einer AMD-CPU, bei der dieloop
Anweisung schnell ist und die innere Schleife nicht so stark beeinträchtigt, ist dies möglicherweise ein schlechteres Verhältnis. Verzweigungsausfälle sind jedoch immer noch ein großer Engpass, da Auslagerungen häufig auftreten (und häufiger auftreten, wenn die unsortierte Region kleiner wird) ).Gleiche Code - Größe für
int8_t
: Verwendunglodsb
/scasb
,AL
und ändern Sie die[rsi/rdi-4]
zu-1
. Derselbe Maschinencode funktioniert im 32-Bit-Modus für 8/32-Bit-Elemente. Der 16-Bit-Modus für 8/16-Bit-Elemente muss mit geänderten Offsets neu erstellt werden (und die 16-Bit-Adressierungsmodi verwenden eine andere Codierung). Aber immer noch 19 Bytes für alle.Es vermeidet die Initiale,
dec ecx
indem es mit dem Element vergleicht, das es gerade geladen hat, bevor es weitergeht. Bei der letzten Iteration der äußeren Schleife lädt sie das letzte Element, prüft, ob es kleiner ist als sie selbst und ist dann fertig. Dies ermöglicht es, mit Größe = 1 zu arbeiten, wo mein BubbleSort fehlschlägt (behandelt es als Größe = 65536).Ich habe diese Version (in GDB) mit dem folgenden Aufrufer getestet: Online ausprobieren ! . Sie können dies auf TIO ausführen, aber natürlich keinen Debugger oder Drucker. Das, das
_start
es aufruft, wird mit exit-status = größtes Element = 99 beendet, sodass Sie sehen können, dass es funktioniert.quelle
cx
undloop
für beide verwenden? Vielleicht eine andere Schleife von hinten nach vorne, damit wir einen Index bis auf Null zählen? (Und inkrementiere,bx
weil der sortierte Teil am Ende ist, zu dem du eine Schleife machst).sub si, cx
als Teil der äußeren Schleife die Verwendung eines Zeigers anstelle der Indizierung in Betracht gezogen , aber ich hatte nicht anlodsb
/ gedachtcmp [si], al
. Ich hatte überlegt , ob ichlodsw
/dec si
oderlodsb
/xchg al,ah
noch einrichten sollcmp ah,al
cld
, oder ich denke, wir könnten diesen Teil der Aufrufkonvention machen. AFAIK ist nach demDF
Löschen kein Standardbestandteil von 16-Bit-Aufrufkonventionen, sondern nur 32/64. Oder ist es nur so, dass man es in einem Bootloader nicht annehmen kann? Bei einer benutzerdefinierten Registeraufrufkonvention ist dies jedoch genauso ein Codefragment wie eine Funktion. Warum also nicht DF = 0? (Und wenn wir wollen, ES = DS, so könnten wirscasb
stattdessen,lodsb
wenn das bequemer ist.)C 72 Bytes
Bubblesort. Das erste Argument ist ein Zeiger auf das Array, das zweite Argument ist die Länge des Arrays. Funktioniert mit gcc.
quelle
MATL ,
1110 BytesExtrem ineffiziente Prüfung aller Permutationen der Eingabe.
Probieren Sie es online!
Erläuterung
quelle
Ruby, 40 Bytes
Auswahl sortieren. Anonyme Funktion; Nimmt die Liste als Argument.
quelle
Python, 120 Bytes
Dies ist wahrscheinlich nicht die kürzeste Antwort, aber ich glaube, dieser Algorithmus gehört hierher. Wenn Sie eine Liste mit ganzen Zahlen aufrufen, werden diese sortiert nach stdout gedruckt. Ich würde es aber nicht mit zu großen Zahlen versuchen.
quelle
MIPS, 68 Bytes
Ich habe vor einiger Zeit eine einfache, nicht optimierte Implementierung für die Blasensortierung geschrieben. Die Anzahl der Bytes beginnt bei
loop
und endet beili $v0, 10
, vorausgesetzt, die Listenadresse und die Listenlänge sind bereits im Speicher.Jetzt warte ich darauf, mit x86 aus dem Wasser geblasen zu werden ...
quelle
swapped=true
Early-Out-Check auslassen und basierend auf der Array-Größe herunterzählen. Siehe meine 20-Byte-x86-16-Version, die eine 8-Bit-Ganzzahl sortiert . Ich könnte eine normale 32- oder 64-Bit-x86-Version erstellen, die irgendwann 32-Bit-Ganzzahlen sortiert, aber 8-Bit-Ganzzahlen im 16-Bit-Modus sind eine Art Sweet Spot für x86.Awk, 66 Bytes
Arrays in awk sind wie Wörterbücher, nicht wie C-Arrays. Die Indizes können nicht zusammenhängend sein und werden nach Bedarf erweitert (und erstellt). Also erstellen wir ein Array
a
für die Eingabe, wobei jede Zeile ein Schlüssel ist. Und wir speichern die min und max Werte. Dann durchlaufen wir eine Schleife von min nach max und drucken alle Schlüssel, die in existierena
.b
ist nur zu vermeiden, wiederholte Verwendung von$0
.quelle
Python 3,
916247 BytesDanke an wnnmaw und Seeq für die Hilfe beim Golfen.
Das Argument
z
sollte eine Liste sein. Dies ist eine Variante der Auswahlsortierung.Ich bin mir nicht sicher, wie es sich
min
schlagen lässtbuilt-in sorting functions
, da ich nicht sicher bin, wie Python implementiert wirdmin
. Hoffentlich ist diese Lösung immer noch in Ordnung. Anregungen zum Golfen in den Kommentaren oder im PPCG-Chat sind willkommen.quelle
def f(z):\nwhile z:m=min(z);z.remove(m);yield m
MATL , 11 Bytes
Probieren Sie es online!
Dies sortiert nach der folgenden Prozedur, die O ( n 2 ) ist:
MATL ist stapelbasiert. Das Array mit den verbleibenden Werten wird oben im Stapel gespeichert. Die entfernten Werte sind der Reihe nach unten aufgeführt. Am Ende des Programms werden alle diese Werte angezeigt. Das Array oben wird ebenfalls angezeigt, aber da es leer ist, wird es nicht angezeigt.
quelle
Pyth -
15131110 BytesZwei Bytes gespart dank @Jakube.
Bogosort.
Probieren Sie es hier online aus .
Ich brauche das nicht,
h
weil wir garantiert keine Duplikate haben.quelle
Im Ernst, 6 Bytes
Probieren Sie es online!
Dies funktioniert genauso wie bei vielen anderen Antworten: Alle Permutationen generieren, Minimum auswählen. Ich habe irgendwie vergessen, dass dies funktionieren würde, während ich an der folgenden Lösung arbeitete.
Erläuterung:
Im Ernst, 25 Bytes (nicht konkurrierend)
Dies wäre wettbewerbsfähig, wenn es keinen Fehler im Shuffle-Befehl gäbe, den ich gerade behoben habe.
Probieren Sie es online! Dies implementiert den besten Sortieralgorithmus aller Zeiten: Bogosort !
Erläuterung:
quelle
MATL,
1716 BytesDank @LuisMendo ein Byte bei der Erstellung eines Null-Arrays gespart
Eimer sortieren. Versuchen Sie es nicht mit einem Bereich von mehr als 2 31 -1.
Probieren Sie es online!
Erläuterung
Bis:
[]
wie in MATLAB mit und vergrößern(
für die ZuweisungsindizierungM
automatische ZwischenablageNeuer Tag, neuer TIL:
vertcat
Erstellt auf magische Weise ein leeres Array, wenn auf dem Stapel nichts zu verketten istquelle
[]
kann durch ersetzt werdenv
. Dies liegt daran, dass die Standardanzahl der Eingabenv
die Anzahl der Elemente im Stapel istvertcat(STACK{:})
Julia,
2827 BytesProbieren Sie es online!
quelle
R, 68 Bytes
Übernimmt die Ein-
i
und Ausgabeno
der sortierten Liste.Erläuterung:
Durch das Vermeiden von Permutationen können große Listen relativ schnell sortiert werden. Der "Trick" ist, dass das Subtrahieren des kleinsten Werts von der Eingabe eine einzelne 0 hinterlässt, die sowohl den kleinsten Wert als auch die Position des kleinsten Werts bestimmt.
quelle
Java 8,
11292 BytesHier ist eine andere Auswahlsorte. Die Eingabe ist eine
List t
Ganzzahl und die sortierte Ausgabe wird standardmäßig ausgegeben.Aktualisieren
quelle
t
existiert, was ihn zu einem Snippet macht. Wir fordern, dass die Einreichungen vollständige Programme oder Funktionen sind , die unsere Standard-E / A-Formate verwenden . Außerdem müssen Importe in die Byteanzahl einbezogen werden. Lassen Sie mich wissen, wenn Sie Fragen haben!Retina, 95
Modifizierte Blasensortierung. Ich vermute, es gibt viel bessere Möglichkeiten, dies zu tun, auch ohne die eingebaute Netzhaut.
n
der Ziffer; Lass fallen-
Schilder fallen.1
als Ziffer; hinzufügen1
zu jedem , so dass Null durch dargestellt wird1
.Probieren Sie es online aus.
quelle
Ruby, 22 Bytes
Eine schnelle Art der Permutation. Läuft in O (n!) Raum und Zeit.
quelle
Clojure,
7335 BytesBogosort :)
Frühere Version:
Reduziert auf eine sortierte Liste,
r
indem es in Teile "kleiner als ich" und "größer als ich" aufgeteilt wird. Ich denke, das ist die Einfügesorte .quelle
recur
auf eine anonyme Funktion zugreifen könntest . Ich wusste auch nichts übershuffle
.Ruby,
2624 BytesAuswahlsortierung, ähnlich der Antwort von Value Ink, jedoch mit einem anderen Ansatz für mehr Golf.
Gemäß der Spezifikation: "Eingabe / Ausgabe kann in jeder von Ihnen gewählten Methode erfolgen, sofern sie für den Menschen lesbar ist". Ich denke, das passt zur Beschreibung, die Ausgabe ist ein Array von Arrays mit einem einzelnen Element.
Beispiel:
quelle
Java 7,
106104 BytesHier ist eine gute alte Blasensorte. Der Funktionsparameter wurde geändert, sodass ich nichts zurückgeben muss. Ich versuche immer noch, ein paar Bytes daraus zu quetschen, damit ich das von jemandem gepostete Java Lambda schlagen kann.
-1 Byte danke an Geobits für den Hinweis, dass normales Tauschen besser ist als
-1 Byte dank Leaky Nun für den Hinweis, dass ich alle int-Deklarationen in die for-Schleife verschieben kann
Probieren Sie es online!
quelle
Ruby, 22 Bytes
Erstellt ein Array aus dem Bereich zwischen den minimalen und maximalen Elementen des Eingabearrays. Gibt den Schnittpunkt zwischen den beiden Arrays zurück.
quelle