Sortieren nach Bozos

8

Einführung

Bei dieser Herausforderung geht es um drei (schlechte) Sortieralgorithmen: Bogosortund zwei weitere Varianten, die ich mir ausgedacht habe (an die ich aber wahrscheinlich irgendwann gedacht habe): Bogoswap(AKA Bozosort) und Bogosmart.

Bogosortfunktioniert, indem das Array vollständig zufällig gemischt und überprüft wird, ob es sortiert wird (aufsteigend). Wenn nicht, wiederholen.

Bogoswapfunktioniert, indem zwei Elemente zufällig ausgewählt und ausgetauscht werden. Wiederholen, bis sortiert (aufsteigend).

Bogosmartfunktioniert, indem zwei Elemente zufällig ausgewählt und nur dann ausgetauscht werden, wenn das Array näher an der Sortierung (aufsteigend) liegt, d. h. wenn das Element mit dem niedrigeren Index ursprünglich größer war als das mit dem höheren. Wiederholen, bis sortiert.

Die Herausforderung

Diese Herausforderung untersucht die Effizienz (oder das Fehlen) jedes dieser drei Sortieralgorithmen. Der Golfcode wird

  1. Generieren Sie ein gemischtes 8-Element-Array der Ganzzahlen 1-8 einschließlich (lesen Sie weiter, um zu sehen, wie Sie dies tun sollten).

  2. Wenden Sie jeden Algorithmus auf dieses Array an. und

  3. Zeigen Sie das ursprüngliche Array an, gefolgt von der Anzahl der für jeden Algorithmus erforderlichen Berechnungen, getrennt durch ein Leerzeichen (nachfolgendes Leerzeichen ok) im Format <ARRAY> <BOGOSORT> <BOGOSWAP> <BOGOSMART>.

Das Programm wird 10 Testfälle erstellen; Sie können alle zehn am Anfang oder einzeln generieren, was auch immer. Beispielausgabe unten.

Einzelheiten:

Denn Bogosortes sollte aufzeichnen, wie oft das Array gemischt wurde.

Denn Bogoswapes sollte die Anzahl der getätigten Swaps aufzeichnen.

Denn Bogosmartes sollte die Anzahl der getätigten Swaps aufzeichnen.

Beispielausgabe:

87654321 1000000 100 1
37485612 9050000 9000 10
12345678 0 0 0 
28746351 4344 5009 5
18437256 10000 523 25
15438762 10000 223 34
18763524 58924 23524 5
34652817 9283 21 445
78634512 5748 234 13
24567351 577 24 34

Ich habe diese Zahlen erfunden; Natürlich druckt Ihr Programm unterschiedliche Ausgaben, jedoch im gleichen Format.

Regeln

  • Alle in Ihrem Programm verwendeten Zufälligkeiten müssen von Pseudozufallszahlengeneratoren stammen, die Ihnen zur Verfügung stehen und ansonsten von Ihnen nicht umfassend berechnet werden. Sie müssen sich keine Sorgen um Samen machen.
  • Es gibt keine zeitliche Begrenzung für die Programme.
  • Die Arrays sind aufsteigend zu sortieren.
  • Nachgestellte Leerzeichen oder ein zusätzlicher Zeilenumbruch sind keine große Sache.
  • Denn Bogosortdas Array muss mit einem beliebigen unvoreingenommenen Mischalgorithmus wie Fisher-Yates oder Knuth Shuffling gemischt werden , der in Ihrer Erklärung explizit angegeben ist. Eingebaute Mischmethoden sind nicht zulässig. Generieren Sie Ihre Testarrays auf die gleiche Weise.
  • Wenn das Array nach dem Mischen oder Austauschen gleich bleibt, zählt es weiterhin und sollte in die Programmanzahl einbezogen werden. Beispielsweise zählt das zufällige Mischen des Arrays zu sich selbst als Mischen, und das Austauschen eines Elements mit sich selbst gilt als Austausch, obwohl keine dieser Operationen das Array ändert.
  • Wenn mein Speicher mir richtig dient, sollte ein 8-Elemente-Array für keinen der drei Algorithmen zu lange dauern. Tatsächlich denke ich, dass ein paar Mal für ein 10-Elemente-Array, als ich es ausprobierte, Bogoswapnur ein paar tausend (oder weniger) tatsächliche Mischvorgänge und weit weniger als 10 Sekunden erforderlich waren.
  • Ihr Code muss die Arrays tatsächlich sortieren und nicht nur erwartete Werte oder mathematische Berechnungen für eine erwartete Antwort angeben.
  • Dies ist eine Code-Golf-Herausforderung, sodass das kürzeste Programm in Bytes gewinnt.

Hier sind einige Beispielschritte für jeden Sortieralgorithmus:

BOGOSORT
56781234
37485612
28471653
46758123
46758123
12685734
27836451
12345678

BOGOSWAP
56781234
16785234
17685234
12685734
12685743
12685734
12485763
12385764
12385764
12345768
12345678

BOGOSMART
56781234
16785234
12785634
12785364
12785364
12385764
12385674
12345678

In diesem Fall würde das Programm ausgeben 56781234 7 10 7und dann zehnmal dasselbe tun. Sie müssen die Arrays nicht drucken, während die Sortierung ausgeführt wird, aber ich habe die obigen Beispielschritte angegeben, damit Sie verstehen, wie jeder Algorithmus funktioniert und wie Berechnungen gezählt werden.

Faraz Masroor
quelle
2
Es gibt 8! = 40.320 mögliche Bestellungen für ein 8-Element-Array. Meine Mathematik ist nicht gut genug, um dies in die erwartete (durchschnittliche) Anzahl von Bogosort-Schritten zu übersetzen. Intuitiv sollte es jedoch mindestens in einer Größenordnung dieser Zahl liegen. Meine Theorie ist, dass Bogosort und Bogoswap die gleiche durchschnittliche Anzahl von Schritten erfordern. Nur dieser eine Schritt Bogoswap ist billiger, daher wird die Zeit kürzer.
Reto Koradi
Ich habe das schon einmal gemacht und glauben Sie mir, Sie werden erstaunt sein, wie unterschiedlich Ihre Gedanken von der Realität sind. Sie werden feststellen, dass Bogosort nicht überraschend die meisten Berechnungen hat, Bogoswap jedoch überraschenderweise eine niedrigere und Bogosmart natürlich noch weniger. Sie werden auch überrascht sein, wie wenig Berechnungen Bogosort benötigt, weit unter 40320.
Faraz Masroor
Kurz gesagt, ich erwarte nicht, dass diese Herausforderung Ihren Computer ruiniert oder Ihren Speicher überfüllt.
Faraz Masroor
2
Verbunden. (Für den Misch- und Bogosort-Teil.)
Martin Ender
Können wir einfach die Anzahl der Schritte aus der mathematisch korrekten Verteilung ausgeben, ohne die Sortierung durchzuführen?
xnor

Antworten:

3

Pyth, 62 60 Bytes

VTjd[jkKJ=boO0=ZS8fqZ=KoO0K0fqZ=XJO.CJ2)0fqZ=Xb*>F=NO.Cb2N)0

Das hat sehr viel Spaß gemacht. Ich bin mir nicht sicher, ob dies gültig ist. Ich verwende wahrscheinlich einige ungeschriebene Lücken.

Eine Beispielausgabe wäre:

23187456 22604 23251 110
42561378 125642 115505 105
62715843 10448 35799 69
72645183 7554 53439 30
61357428 66265 6568 77
62348571 1997 105762 171
78345162 96931 88866 241
17385246 51703 7880 80
74136582 36925 19875 100
26381475 83126 2432 25

Erläuterung:

Meine Shuffle-Funktion verwendet die eingebaute Funktion order-by. Grundsätzlich ordne ich jedem Element der Liste eine Zufallszahl des Intervalls zu [0-1)und sortiere die Liste nach ihnen. Dies gibt mir ein unvoreingenommenes zufälliges Mischen.

Äußere Schleife

Der VTzu Beginn wiederholt den folgenden Code 10 Mal.

Vorbereitung

jkKJ=boO0=ZS8
           S8        create the list [1, 2, 3, 4, 5, 6, 7, 8]
         =Z          and store in Z
      oO0            shuffle
    =b               and store in b
   J                 and store in J
  K                  and store in K (3 copies of the same shuffled array)
jkK                  join K with ""

Bogosort

fqZ=KoO0K0 
     oO0K            shuffle K
   =K                and store the result in K
f        0           repeat ^ until:
 qZ K                  Z == K
                     and give the number of repeats

Bogoswap

fqZ=XJO.CJ2)0  
       .CJ2          give all possible pairs of elements of J
      O              take a random one
    XJ     )         swap these two elements in J
   =                 and store the result in J
f           0        repeat ^ until:
 qZ K                  Z == K
                     and give the number of repeats

Bogosmart

fqZ=Xb*>F=NO.Cb2N)0
            .Cb2     give all possible pairs of elements of b
           O         take a random one
         =N          assign it to N
       >F N          check if N[0] > N[1]
      *         N    multiply the boolean with N
    Xb           )   swap the two (or zero) values in b
   =                 and assign to b
f                 0  repeat ^ until:
 qZ                    Z == b
                     and give the number of repeats

Drucken

jd[
  [                  put all 4 values in a list
jd                    join by spaces and print
Jakube
quelle
=JXJO.cJ2)ist das gleiche wie =XJO.cJ2)- erweiterte Zuordnung. Gleiches gilt für =bXbspäter. Ich denke auch, dass Swaps die Paare mit Ersatz ( .C)
auswählen sollen
@isaacg Danke, korrigierte Dinge. Nicht sicher, ob entweder .coder .Cerlaubt sind. Zum Beispiel .C[3 1 2)2gibt das Paar nicht zurück [2, 1]. Welches ist eine Eigenschaft, die ich in meinem Algorithmus ausnutze.
Jakube
vielleicht *JJdann? Es ist auch ein Zeichen kürzer, was schön ist.
isaacg
2

JavaScript ( ES6 ), 319 345

Es überrascht nicht, dass dies ziemlich lang ist.

Für Random Shuffle wird @ core1024 gutgeschrieben (besser als meins für das gleiche Chellenge)

Testen Sie das Snippet (Firefox nur wie gewohnt)

// FOR TEST : redefine console
var console = { log: (...p)=>O.innerHTML += p.join(' ')+'\n' }
// END 

// Solution
R=n=>Math.random()*n|0, 
S=a=>(a.map((c,i)=>(a[i]=a[j=R(++i)],a[j]=c)),a), // shuffle
T=f=>{for(a=[...z];a.join('')!=s;)f(a)}, // apply sort 'f'  algorithm until sorted

s='12345678';
for(i=0;i<10;i++)
  z=S([...s]),
  n=l=m=0,
  T(a=>S(a,++n)),
  T(a=>(t=a[k=R(8)],a[k]=a[j=R(8)],a[j]=t,++m)),
  T(a=>(t=a[k=R(8)],u=a[j=R(8)],(t<u?j<k:k<j)&&(a[k]=u,a[j]=t,++l))),
  console.log(z.join(''),n,m,l)
<pre id=O></pre>

edc65
quelle
Der Link "Code-Snippet ausführen" funktioniert bei mir nicht. Ich bin mir nicht sicher, ob es mein Browser / System ist, aber die Snippet-Links haben in der Vergangenheit für mich funktioniert.
Reto Koradi
Gleich, das Code-Snippet funktioniert nicht in meinem Browser
Faraz Masroor
2
@Reto et al. EcmaScript 6: Nur unter Firefox ausführen.
edc65