Die Idee für diese Code-Herausforderung ist einfach: Bei einer gegebenen Matrix von Ganzzahlen sortieren wir sie durch Anwenden von Bewegungen im Rubik-Stil. Dies bedeutet, dass Sie eine einzelne Zeile oder Spalte auswählen und ihre Elemente in eine beliebige Richtung drehen können:
[1, 3, 2, 4] => [3, 2, 4, 1] (rotate left for rows/up for columns)
[1, 3, 2, 4] => [4, 1, 3, 2] (rotate right for rows/down for columns)
Sortieren Sie also bei einer Matrix von Ganzzahlen beliebiger Dimension die Elemente, indem Sie nur diese Transformationen im Rubik-Stil anwenden. Eine Matrix
gilt als sortiert, wenn seine Elemente der folgenden Einschränkung entsprechen:
I / O
- Die Eingabe ist eine Matrix aus positiven ganzen Zahlen ohne wiederholte Werte.
- Das Ergebnis sind die Bewegungen, die zum Sortieren erforderlich sind. Da dies kein Code Golf Herausforderung ist und Sie nicht Sorge über seine Länge benötigt, ist das vorgeschlagene Format für jede Bewegung ,
#[UDLR]
wo#
die Nummer der Zeile oder Spalte zu bewegen (0-indiziert) und[UDLR]
ist ein einzelne Zeichen, dass Bereich, der angibt, ob die Bewegung nach oben / unten (für Spalten) oder links / rechts (für Zeilen) erfolgt. Dies1U
würde bedeuten, dass "die 1. Spalte nach oben verschoben wird", aber1R
"die 1. Zeile nach rechts verschoben wird". Bewegungen werden durch Komma getrennt sein, so wird eine Lösung wie folgt ausgedrückt werden:1R,1U,0L,2D
.
Wertung
Der Versuch, eine Matrix auf diese Weise zu sortieren, kann kostspielig sein, da es viele mögliche Kombinationen von Zügen gibt und es auch viele mögliche Listen von Zügen gibt, die sie sortieren können. Daher besteht das Ziel darin, einen Code zu schreiben, der das N * sortiert. N Matrizen unten. Die Punktzahl ist die größte Größe N, die Sie in einem angemessenen Zeitraum 1 ohne Fehler lösen können (je größer die Größe der gelösten Matrix, desto besser). Im Falle eines Gleichstandes ist der Gleichstand die Anzahl der Bewegungen auf Ihrem gefundenen Weg (je kürzer der Weg, desto besser).
Beispiel: Wenn ein Benutzer A eine Lösung für N = 5 und B eine Lösung für N = 6 findet, gewinnt B unabhängig von der Länge beider Pfade. Wenn beide Lösungen für N = 6 finden, aber die von A gefundene Lösung 50 Schritte und die von B 60 Schritte hat, gewinnt A.
Erklärungen zur Funktionsweise Ihres Codes werden dringend empfohlen. Veröffentlichen Sie die gefundenen Lösungen, damit wir sie testen können . Sie können Pastebin oder ähnliche Tools verwenden, wenn die Lösungen zu groß sind. Außerdem wird eine Schätzung der Zeit, die Ihr Code benötigt, um Ihre Lösungen zu finden, geschätzt.
Testfälle
Die folgenden Matrizen ( Pastebin-Link für eine kopierfähigere Version) wurden ausgehend von bereits sortierten Matrizen erstellt, indem sie mit 10K zufälligen Bewegungen im Rubik-Stil verschlüsselt wurden:
Klartext-Testfälle:
[[8, 5, 6], [11, 10, 1], [3, 15, 13]]
[[21, 10, 12, 16], [17, 6, 22, 14], [8, 5, 19, 26], [13, 24, 3, 1]]
[[1, 13, 8, 16, 5], [9, 40, 21, 26, 22], [11, 24, 14, 39, 28], [32, 19, 37, 3, 10], [30, 17, 36, 7, 34]]
[[34, 21, 40, 22, 35, 41], [18, 33, 31, 30, 12, 43], [19, 11, 39, 24, 28, 23], [44, 1, 36, 5, 38, 45], [14, 17, 9, 16, 13, 26], [8, 3, 47, 6, 25, 4]]
[[20, 36, 17, 1, 15, 50, 18], [72, 67, 34, 10, 32, 3, 55], [42, 43, 9, 6, 30, 61, 39], [28, 41, 54, 27, 23, 5, 70], [48, 13, 25, 12, 46, 58, 63], [52, 37, 8, 45, 33, 14, 68], [59, 65, 56, 73, 60, 64, 22]]
[[85, 56, 52, 75, 89, 44, 41, 68], [27, 15, 87, 91, 32, 37, 39, 73], [6, 7, 64, 19, 99, 78, 46, 16], [42, 21, 63, 100, 4, 1, 72, 13], [11, 97, 30, 93, 28, 40, 3, 36], [50, 70, 25, 80, 58, 9, 60, 84], [54, 96, 17, 29, 43, 34, 23, 35], [77, 61, 82, 48, 2, 94, 38, 66]]
[[56, 79, 90, 61, 71, 122, 110, 31, 55], [11, 44, 28, 4, 85, 1, 30, 6, 18], [84, 43, 38, 66, 113, 24, 96, 20, 102], [75, 68, 5, 88, 80, 98, 35, 100, 77], [13, 21, 64, 108, 10, 60, 114, 40, 23], [47, 2, 73, 106, 82, 32, 120, 26, 36], [53, 93, 69, 104, 54, 19, 111, 117, 62], [17, 27, 8, 87, 33, 49, 15, 58, 116], [95, 112, 57, 118, 91, 51, 42, 65, 45]]
Bitte fragen Sie nach mehr, wenn Sie sie alle lösen. :-) Und vielen Dank an die Leute, die mir geholfen haben, diese Herausforderung im Sandkasten zu verfeinern .
1 Eine angemessene Zeitspanne: Jede Zeitspanne, die unsere Geduld beim Testen Ihrer Lösung nicht beeinträchtigt. Beachten Sie, dass TIO den Code nur 60 Sekunden lang ausführt. Wenn diese Zeit überschritten wird, können wir den Code auf unseren Computern testen. Beispiel: Mein ineffizienter Algorithmus benötigt ein paar Millisekunden, um Matrizen der Größenordnung 3x3 und 4x4 zu lösen, aber ich habe ihn gerade mit einer 5x5-Matrix getestet und es dauerte 317 Sekunden, um ihn zu lösen (in über 5 Millionen Bewegungen, sehr lustig, wenn wir das betrachten Die zu lösende Matrix wurde nur 10K-mal verschlüsselt . Ich habe versucht, die Anzahl der Bewegungen auf weniger als 10 KB zu reduzieren, aber ich habe mich nach 30 Minuten ergeben, nachdem ich den Code ausgeführt hatte.
O(input size)
? Für eine 5x5 Matrix wäre dasO(25)
? Das scheint extrem schnell zu sein, also wäre ich sehr interessiert, diesen Algorithmus oder Ihre Implementierung zu sehen. EDIT: Sie wissen, dass wir die 'verschlüsselte' Matrix eingeben und die Bewegungen ausgeben, richtig? Nicht umgekehrt.Antworten:
Nim
Probieren Sie es online!
Ein kurzer Versuch, den Algorithmus der Torus-Rätsellösung aus einem Artikel in Algorithms 2012, 5, 18-29 zu implementieren, den ich in den Kommentaren erwähnt habe.
Akzeptiert die Eingabematrix in abgeflachter Form als Zeile mit durch Leerzeichen getrennten Zahlen.
Hier ist auch ein Validator in Python 2 . Es werden zwei Zeilen als Eingabe verwendet: die ursprüngliche verwürfelte Matrix in derselben Form wie der Hauptcode und die vorgeschlagene Bewegungssequenz. Die Ausgabe des Validators ist die Matrix, die sich aus der Anwendung dieser Züge ergibt.
Erläuterung
Im ersten Teil des Algorithmus ordnen wir alle Zeilen mit Ausnahme der letzten an.
proc triangle
In Abb. 2 präsentieren die Autoren 8 mögliche Muster und die entsprechenden Abfolgen von Zügen, aber in meinem Code wurden tatsächlich alle Fälle von nur 5 Mustern abgedeckt, sodass Nr. 1, 5 und 6 werden nicht verwendet.
Im zweiten Teil wird die letzte Reihe mit Ausnahme der beiden letzten Elemente durch Ausführen von "
proc line
Dreieckdrehungen " auf einer Linie ( ) angeordnet, die jeweils aus zwei Dreieckdrehungen besteht (siehe Abb. 3 des Artikels).proc swap
Update: Neu hinzugefügt
proc rotations
, wodurch die Bewegungsrichtung umgekehrt wird, wenn dies zu weniger Schritten führen würde.quelle
7L,7L,7L,7L,7D,7D,7D,7D
gibt, die reduziert und8R,8R,8R,8R,8R,8R,8R
dann8L,8L
für eine 9x9-Matrix konvertiert werden können.Python 2 , Größe 100 in <30 Sekunden bei TIO
Probieren Sie es online! Link enthält drei kleine Testfälle mit voller Bewegungsausgabe sowie einen unbeaufsichtigten Test von 100x100, um zu zeigen, dass der Code funktioniert (die Bewegungsausgabe würde die TIO-Grenzwerte überschreiten). Erläuterung: Der Code versucht, eine Einfügesortierung für das Array durchzuführen und baut sie dabei in aufsteigender Reihenfolge auf. Für alle Zeilen mit Ausnahme der letzten Zeile gibt es eine Reihe von Fällen:
Die obigen Drehungen werden in welcher Richtung auch immer durchgeführt, um die Anzahl der Schritte zu minimieren; Ein Quadrat der Größe 2 wird unabhängig von der obigen Beschreibung immer mit Links- und Aufwärtsbewegungen gelöst.
Bevor die untere Reihe fertiggestellt ist, wird sie gedreht, um die Gesamtentfernung zu minimieren, aber auch um sicherzustellen, dass die Parität der unteren Reihe gleichmäßig ist, da sie durch den letzten Teil des Algorithmus nicht geändert werden kann. Gibt es mehr als eine Umdrehung mit derselben Mindestentfernung, wird die Umdrehung mit der geringsten Anzahl von Bewegungen ausgewählt.
Der Algorithmus für die unterste Zeile basiert auf einer Sequenz mit 7 Operationen, bei der die Elemente in drei Spalten ausgetauscht werden. Die Reihenfolge wird auf jede der verbleibenden Nummern der untersten Reihe angewendet, um sie an den gewünschten Ort zu bringen. Wenn möglich, wird das Element an dieser Position an die gewünschte Position verschoben. Wenn jedoch ein gerader Tausch erforderlich ist, wird das Element einfach in die nächste verfügbare Spalte verschoben, damit es beim nächsten Mal repariert werden kann.
quelle