Schreiben Sie das kürzeste Programm, das Rubiks Würfel (3 * 3 * 3) innerhalb eines angemessenen Zeitraums löst und sich bewegt (z. B. maximal 5 Sekunden auf Ihrer Maschine und weniger als 1000 Züge).
Die Eingabe erfolgt im Format:
UF UR UB UL DF DR DB DL FR FL BR BL UFR URB UBL ULF DRF DFL DLB DBR
(Diese spezielle Eingabe repräsentiert den gelösten Würfel).
Die ersten 12 2-stelligen Zeichenfolgen sind die Kanten in den Positionen UF, UR, ... BL (U = oben, F = vorne, R = rechts, B = hinten, L = links, D = unten), dann die nächsten 8 3-stellige Zeichenfolgen sind die Ecken an den Positionen UFR, URB, ... DBR.
Die Ausgabe sollte eine Folge von Zügen in diesem Format enthalten:
D+ L2 U+ F+ D+ L+ D+ F+ U- F+
Während D1 oder D + das Drehen der D-Seite (nach unten) im Uhrzeigersinn um 90 Grad darstellt, dreht L2 die L-Seite um 180 Grad, U3 oder U- das Drehen der U-Seite gegen den Uhrzeigersinn um 90 Grad.
Bei Buchstaben wird die Groß- / Kleinschreibung nicht berücksichtigt, und Leerzeichen sind optional.
Die obige Ausgabe ist beispielsweise für die folgende Eingabe korrekt:
RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU
Weitere Details finden Sie in Tomas Rokickis Würfelwettbewerb , mit der Ausnahme, dass die Wertung direkt nach Dateigröße erfolgt, wie bei einem normalen Code-Golfproblem. Ein Online-Tester ist ebenfalls enthalten.
Als Referenz ist die kürzeste bereits geschriebene Lösung der letzte Eintrag in der Liste der Gewinner des Würfelwettbewerbs
Für diejenigen, die Schwierigkeiten haben, das Layoutformat zu visualisieren:
0-1 2-3 4-5 6-7 8-9 10-11 12-13 14-15 16-17 18-19 20-21 22-23 24-25-26 27-28-29 30-31-32 33-34-35 36-37-38 39-40-41 42-43-44 45-46-47
UF UR UB UL DF DR DB DL FR FL BR BL UFR URB UBL ULF DRF DFL DLB DBR
Front:
+-------+-------+-------+
/ / / /|
/ 30 / 4 / 27 / |
+-------+-------+-------+ |
/ / / /|28+
/ 6 / / 2 / | /|
+-------+-------+-------+ |/ |
/ / / /|3 + |
/ 33 / 0 / 24 / | /|21+
+-------+-------+-------+ |/ | /|
| | | |26+ |/ |
| 35 | 1 | 25 | /| + |
| | | |/ | /|47+
+-------+-------+-------+ |/ | /
| | | |17+ |/
| 18 | | 16 | /|11+
| | | |/ | /
+-------+-------+-------+ |/
| | | |37+
| 40 | 9 | 38 | /
| | | |/
+-------+-------+-------+
Hidden faces:
+-------+-------+-------+
/| | | |
/ | 31 | 5 | 29 |
+ | | | |
/|32+-------+-------+-------+
/ | /| | | |
+ |/ | 22 | | 20 |
/|7 + | | | |
/ | /|23+-------+-------+-------+
+ |/ | /| | | |
|34+ |/ | 44 | 13 | 46 |
| /| + | | | |
|/ | /|43+-------+-------+-------+
+ |/ | / / / /
|19+ |/ 42 / 12 / 45 /
| /|15+-------+-------+-------+
|/ | / / / /
+ |/ 14 / / 10 /
|41+-------+-------+-------+
| / / / /
|/ 39 / 8 / 36 /
+-------+-------+-------+
quelle
Antworten:
C ++ - 1123
Da bisher noch niemand eine Antwort gepostet hat, habe ich beschlossen, meine 2004-Lösung zu vereinfachen und zu verbessern. Es ist immer noch weit hinter der kürzesten, die ich in der Frage erwähnt habe.
Es ist nicht zufällig, aber es geht auch nicht einfach vonstatten. Es löst zuerst die Kanten, dann die Ecken. Bei jedem Schritt werden verschiedene Kombinationen von bis zu 4 Algorithmen und einfachen Gesichtszügen (nacheinander, nicht zufällig) ausprobiert, bis sich die Anzahl der gelösten Teile verbessert hat. Anschließend werden die Schritte wiederholt, bis sie gelöst sind. Es werden 2 Algorithmen für Kanten und 2 für Ecken verwendet, die in alle Würfelpositionen übersetzt werden.
Beispielausgabe für
RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU
:L2F3B2F3B1U3F1B3R2F3B1U3F1B3D2F2L3D2L1U2B1L1R3U2R1L3B1U2R1U2L1F1B3U2B1F3L1U2L3R1D3L1R3B2L3R1D3L1R3L3R1D3L1R3B2L3R1D3L1R3B3F1D3B1F3R2B3F1D3B1F3U2F3L3R1B3L1R3U2L3R1B3L1R3F1D2F1L1R3D2R1L3F1D2F3L2U1B1F3L2F1B3U1L2R3L1F3R1L3U2R3L1F3R1L3U1F2U1L1R3F2R1L3U1F2U3L3U3L1U3L3U2L1R1U1R3U1R1U2R3F3U3F1U3F3U2F1B1U1B3U1B1U2B3L1B3R3B1L3B3R1B1B3D3B1D3B3D2B1F1D1F3D1F1D2F3R1F3L3F1R3F3L1F1R3B3R1B3R3B2R1L1B1L3B1L1B2L3R1D3L3D1R3D3L1D1B3D3B1D3B3D2B1F1D1F3D1F1D2F3U3R3U1R3U3R2U1D1R1D3R1D1R2D3
(234 Züge, 0,3 Sek. Hier)
quelle
Python 1166 Bytes
Aus Gründen der Lesbarkeit wurde eine beträchtliche Menge an Leerzeichen gelassen. Die Größe wird nach dem Entfernen dieser Leerzeichen gemessen und das Ändern von verschiedenen Einrückungen zu
Tab
,Tab
Space
,Tab
Tab
etc. Ich habe auch alle Golf vermieden , das die Leistung zu stark beeinträchtigt.Beispielnutzung:
Dies ist eine Implementierung des Thistlethwaite-Algorithmus, bei der für jeden Schritt eine IDA * -Suche verwendet wird. Da alle heuristischen Tabellen im laufenden Betrieb berechnet werden müssen, wurden mehrere Kompromisse eingegangen, wobei eine Heuristik normalerweise in zwei oder mehr Teile gleicher Größe aufgeteilt wurde. Dies beschleunigt die Berechnung der heuristischen Tabellen um ein Vielfaches und verlangsamt die Suchphase, normalerweise nur geringfügig. Dies kann jedoch in Abhängigkeit vom ursprünglichen Cube-Status erheblich sein.
Variablenindex
T
- die heuristische Haupttabelle.S
- ein gelöster Würfelzustand. Jedes einzelne Stück wird als Bitmaske gespeichert und als Zeichen dargestellt. Ein gelöster Orientierungsvektor ist als der Nullvektor definiert.I
- die verschiedenen Wendungen in der Reihenfolge, in der sie aus dem Suchfeld entfernt werden.G
- die Gruppen für Twist-Permutationen, die als auszutauschende Paare gespeichert sind. Jedes Byte in der komprimierten Zeichenfolge codiert für ein Paar. Für jede Drehung sind sechs Tauschvorgänge erforderlich: drei für den Kantenzyklus und drei für den Eckenzyklus. Die komprimierte Zeichenfolge enthält nur druckbare ASCII-Zeichen (Zeichen 32 bis 126).M
- eine Funktion, die einen Zug ausführt, gegeben von G.N
- wandelt eine Permutation von vier Objekten zu Kodierungszwecken in eine Zahl um.H
- berechnet den heuristischen Wert für den angegebenen Würfelstatus, der zum Nachschlagen der Verschiebungstiefe von T verwendet wird.P
- Führen Sie eine Suche in einer einzelnen Tiefe einer einzelnen Phase des Algorithmus durch.s
- Der Permutationsstatus des Eingabewürfels.o
- Der Orientierungsvektor des Eingabewürfels.Performance
Unter Verwendung des Datensatzes von Tomas Rokicki ergab dieses Skript einen Durchschnitt von 16,02 Drehungen pro Lösung (maximal 35) mit einer durchschnittlichen Zeit von 472 ms (i5-3330 CPU @ 3,0 Ghz, PyPy 1.9.0). Die minimale Lösungszeit betrug 233 ms mit einem Maximum von 2,97 s, Standardabweichung 0,488. Nach den Bewertungsrichtlinien des Wettbewerbs (Leerraum wird nicht gezählt, Schlüsselwörter und Bezeichner zählen bei einer Länge von 870 als ein Byte) hätte die Gesamtpunktzahl 13.549 betragen.
In den letzten 46 Fällen (den Zufallszuständen) wurden durchschnittlich 30,83 Drehungen pro Lösung mit einer durchschnittlichen Zeit von 721 ms ermittelt.
Anmerkungen zum Thistlethwaite-Algorithmus
Hier finden Sie eine kurze Erklärung für alle, die eine Implementierung des Thistlethwaite-Algorithmus versuchen möchten .
Der Algorithmus arbeitet nach einem sehr einfachen Lösungsprinzip zur Raumreduzierung. Das heißt, reduzieren Sie den Würfel auf einen Zustand, in dem eine Teilmenge von Drehungen nicht erforderlich ist, um ihn zu lösen, reduzieren Sie ihn auf einen kleineren Lösungsraum und lösen Sie den Rest mit nur den wenigen verbleibenden Drehungen.
Thistlethwaite schlug ursprünglich vor
<L,R,F,B,U,D>
→<L,R,F,B,U2,D2>
→<L,R,F2,B2,U2,D2>
→<L2,R2,F2,B2,U2,D2>
. Angesichts des Eingabeformats halte ich es jedoch für einfacher, zuerst auf<L,R,F2,B2,U,D>
(keine VierteldrehungF
oderB
) zu reduzieren und dann,<L2,R2,F2,B2,U,D>
bevor schließlich der halbe Drehungszustand erreicht wird. Anstatt genau zu erklären, warum dies der Fall ist, wird es meiner Meinung nach offensichtlich, nachdem die Kriterien für jeden Staat definiert wurden.<L,R,F,B,U,D>
⇒<L,R,F2,B2,U,D>
Um zu beseitigen
F
undB
Vierteldrehungen, nur die Kanten müssen korrekt ausgerichtet sein. Gilles Roux hat auf seiner Website eine sehr gute Erklärung dafür, was "richtige" und "falsche" Orientierung ist, also überlasse ich die Erklärung ihm. Aber im Grunde (und das ist , warum dieses Eingabeformat so günstig istF
undB
Beseitigung), wird eine Kante Cubie richtig ausgerichtet , wenn sie die folgende Regex übereinstimmt:[^RL][^UD]
. Eine korrekte Ausrichtung wird in der Regel mit0
und falsch mit gekennzeichnet1
. Grundsätzlich könnenU
undD
Aufkleber möglicherweise nicht auf denR
oderL
Flächen oder an den Kanten der beliebigenU
oderD
Kantenwürfel erscheinen, oder sie können nicht an Ort und Stelle verschoben werden, ohne dass einF
oder erforderlich istB
Vierteldrehung.<L,R,F2,B2,U,D>
⇒<L2,R2,F2,B2,U,D>
Zwei Kriterien hier. Zunächst müssen alle Ecken richtig ausgerichtet werden, und die zweite, die jeweils die für die Mittelschicht Cubies (
FR
,FL
,BR
,BL
) muss irgendwo in der Mittelschicht sein. Eine Eckausrichtung ist aufgrund des Eingabeformats sehr einfach zu definieren: die Position des erstenU
oderD
. Hat zum BeispielURB
Orientierung0
(richtig orientiert),LDF
hat Orientierung1
undLFU
hat Orientierung2
.<L2,R2,F2,B2,U,D>
⇒<L2,R2,F2,B2,U2,D2>
Hier gelten folgende Kriterien: Jedes Gesicht darf nur Aufkleber von seinem Gesicht oder von dem Gesicht direkt gegenüber enthalten. Zum Beispiel kann es auf dem
U
Gesicht nurU
undD
Aufkleber geben, auf demR
Gesicht nurR
undL
Aufkleber geben, auf demF
Gesicht nurF
undB
Aufkleber usw. Der einfachste Weg, dies sicherzustellen, besteht darin, zu überprüfen, ob sich jedes Kantenstück in befindet seine "Scheibe" und jedes Eckstück in seiner "Umlaufbahn". Zusätzlich muss auf die Kanten-Ecken-Parität geachtet werden. Wenn Sie jedoch nur auf Eckparität prüfen, ist auch die Kantenparität garantiert und umgekehrt.Wie Drehungen die Orientierung beeinflussen
U
undD
Verdrehungen wirken sich weder auf die Kantenausrichtung noch auf die Eckenausrichtung aus. Die Teile können direkt getauscht werden, ohne den Ausrichtungsvektor zu aktualisieren.R
undL
Drehungen wirken sich nicht auf die Kantenausrichtung aus, wirken sich jedoch auf die Eckenausrichtung aus. Je nachdem, wie Sie Ihren Zyklus definieren, ist die Änderung der Eckenausrichtung entweder+1, +2, +1, +2
oder vollständig+2, +1, +2, +1
modulo3
. Es ist zu beachten, dassR2
undL2
Drehungen die Eckenorientierung nicht beeinflussen, da+1+2
Null-Modulo ist3
, wie es ist+2+1
.F
undB
wirken sich sowohl auf die Kantenorientierungen als auch auf die Eckenorientierungen aus. Kantenorientierungen werden zu+1, +1, +1, +1
(Mod 2), und Eckenorientierungen sind dieselben wie fürR
undL
. Beachten Sie diesF2
undB2
beeinflussen Sie weder die Kantenausrichtungen noch die Eckenausrichtungen.quelle
<L,R,F,B,U,D>
-><L2,R2,F2,B2,U,D>
-><I>
. Es sind maximal 29 Drehungen erforderlich, um einen Würfel zu lösen (anstelle von 52 für Thistlethwaite), aber es sind auch sehr große Nachschlagetabellen erforderlich, deren Generierung "on the fly" unpraktisch wäre.Ruby, 742 Zeichen
Der obige Ruby-Code ist noch nicht vollständig golfen. Es gibt immer noch Möglichkeiten, den Code weiter zu verbessern (aber es reicht schon als Starter).
Der Würfel wird schichtweise aufgelöst, es wird jedoch kein spezifischer Algorithmus verwendet, sondern es werden zufällige Abfolgen von Zügen ausgeführt, bis der Würfel aufgelöst ist.
Aufgrund der Wahrscheinlichkeit kann es manchmal länger als 5 Sekunden dauern, bis der Würfel gelöst ist. In seltenen Fällen sind mehr als 1000 Züge erforderlich.
Beispielausgabe (für Eingabe 'RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU') ist 757 Züge:
Es ist möglich, die Anzahl der Züge erheblich zu reduzieren, wenn die gleichen Züge in Gruppen zusammengefasst werden. Daher kann man die Ausgabe gerne ersetzen
quelle
FU FR RU BR DB LD LU LB LF RD DF BU FRU BUR FDR DLB DFL LUB FUL DBR
U1 U1 U1
in einer einzigen zusammenfassenU3
?