Drüben bei unseren Freunden bei Puzzling.SE wurde das folgende Rätsel gestellt: Ist dieses chromatische Rätsel immer lösbar? von Edgar G. Sie können es spielen hier .
Puzzle Erklärung
Bei einem m x n
Raster mit Kacheln mit drei verschiedenen Farben können Sie zwei benachbarte Kacheln auswählen , wenn ihre Farben unterschiedlich sind . Diese beiden Kacheln werden dann in die dritte Farbe konvertiert, dh die eine Farbe, die von diesen beiden Kacheln nicht dargestellt wird. Das Rätsel ist gelöst, wenn alle Kacheln die gleiche Farbe haben . Anscheinend kann man beweisen, dass dieses Rätsel immer lösbar ist, wenn es weder durch 3 teilbar m
noch n
teilbar ist.
Dies erfordert natürlich einen Lösungsalgorithmus. Sie werden eine Funktion oder ein Programm schreiben, das dieses Rätsel löst. Beachten Sie, dass Funktionen mit 'Nebenwirkungen' (dh die Ausgabe ist aktiviert stdout
und nicht in einem unangenehmen Datentyp-Rückgabewert) ausdrücklich zulässig sind.
Input-Output
Die Eingabe wird eine sein , m x n
Matrix , bestehend aus den ganzen Zahlen 1
, 2
und 3
(oder 0
, 1
, 2
wenn praktisch). Sie können diese Eingabe in jedem vernünftigen Format vornehmen. Beide m
und n
sind >1
und nicht durch 3 teilbar. Sie können davon ausgehen, dass das Rätsel nicht gelöst ist
Sie lösen dann das Rätsel. Dies beinhaltet eine wiederholte Auswahl zweier benachbarter Kacheln, die „konvertiert“ werden sollen (siehe oben). Sie geben die beiden Koordinaten dieser Kacheln für jeden Schritt aus, den Ihr Lösungsalgorithmus ausgeführt hat. Dies kann auch in jedem vernünftigen Ausgabeformat erfolgen. Sie können zwischen einer 0-basierten und einer 1-basierten Indexierung Ihrer Koordinaten wählen und festlegen, ob Zeilen oder Spalten zuerst indexiert werden sollen. Bitte erwähnen Sie dies jedoch in Ihrer Antwort.
Ihr Algorithmus sollte innerhalb einer angemessenen Zeit auf dem ursprünglichen 8x8-Gehäuse ausgeführt werden. Brute-Forcing ist ausdrücklich untersagt, dh Ihr Algorithmus sollte O(k^[m*(n-1)+(m-1)*n])
mit k
der für die Lösung erforderlichen Anzahl von Schritten ausgeführt werden. Die Lösung muss jedoch nicht optimal sein. Der in der verknüpften Frage angegebene Beweis kann Ihnen eine Vorstellung davon geben, wie dies zu tun ist (z. B. zuerst alle Spalten unter Verwendung nur vertikal benachbarter Kacheln und dann alle Zeilen).
Testfälle
In diesen Testfällen sind die Koordinaten 1-basiert und die Zeilen werden zuerst indiziert (wie MATLAB / Octave und wahrscheinlich viele andere).
Input:
[1 2]
Output: (result: all 3's)
[1 1],[1,2]
Input:
[ 1 2
3 1 ]
Output: (result: all 1's)
[1 1],[2 1] (turn left column into 2's)
[2 1],[2 2] (turn right column into 3's)
[1 1],[1 2] (turn top row into 1's)
[2 1],[2 2] (turn bottom row into 1's)
Input:
[1 2 3 2
3 2 1 1]
Output: (result: all 3's)
[1 1],[1 2]
[1 3],[1 4]
[1 2],[1 3]
[1 1],[1 2]
[1 2],[1 3]
[1 1],[1 2]
[1 3],[1 4]
[2 1],[2 2]
[1 1],[2 1]
[1 2],[2 2]
[1 3],[2 3]
[1 4],[2 4]
Auf Wunsch kann ich einen Pastebin größerer Testfälle posten, aber ich denke, das sollte ausreichen.
quelle
Antworten:
Ruby, 266 Bytes
Mehr oder weniger nur ein Port der Octave-Lösung, mit der Ausnahme, dass zuerst Zeilen und nicht Spalten aufgelöst werden. Input ist ein Array von Arrays, wobei die inneren Arrays die Zeilen sind. Ausgangsbewegungen sind
[row, column, row, column]
. TestsuiteUngolfed mit Erklärung
quelle
intersect
es sich um ein sointersect
, ich weiß nicht , ob Sie , dass die Art und Weise mir arbeitet beheben können , weil Ruby -find
on - Funktionen arbeitet grundsätzlich, und Ihrfunction
Schlüsselwort ist genauso sperrig.find
- danke! Trotzdem, nirgendwo in der Nähe, Sie zu schlagen ...Oktave,
334313 BytesDa die Herausforderung etwas abschreckend wirken mag, präsentiere ich meine eigene Lösung. Ich habe formal nicht bewiesen, dass diese Methode funktioniert (ich vermute, das wird der Beweis sein, dass der Algorithmus niemals in einer Schleife hängen bleibt), aber bisher funktioniert es perfekt, 100x100 Testfälle innerhalb von 15 Sekunden durchzuführen. Beachten Sie, dass ich mich für eine Funktion mit Nebenwirkungen entschieden habe und nicht für eine, die alle Koordinaten zurückgibt, da ich dadurch einige Bytes gespart habe. Koordinaten sind zeilenweise, 1-basiert und wie folgt formatiert
row1 col1 row2 col2
. Eingabefarben sind,0,1,2
da dies besser funktioniertmod
, auf Kosten der Verwendungnumel
und nichtnnz
. Golf-Version: Bearbeiten: Mit einer Technik aus der Antwort von Kevin Lau wurden einige weitere Bytes gespeichert.Beispiel GIF des Lösungsalgorithmus:
Ungolfed-Version:
quelle
Lua,
594575559 BytesWarnung Es gibt noch viel Arbeit, bevor ich mit dem Golfen fertig bin! Zumindest sollte ich das unter 500 Bytes aushalten können. Im Moment ist es die erste Lösung, die funktioniert hat, und ich arbeite immer noch daran.
Ich werde eine vollständige Erklärung geben, sobald ich fertig bin.
quelle
Rust,
496495 BytesLeider kann ich OP nicht schlagen, aber für eine Rust-Antwort bin ich mit dem bytecount ziemlich zufrieden.
Eingabe: ein Zahlenvektor sowie die Anzahl der Spalten. Z.B
Ausgänge
zur Kommandozeile.
Ich löse zuerst jede Zeile und löse dann die resultierende Spalte nur einmal, aber drucke die Schritte für alle Spalten. Also ist es eigentlich recht effizient :-P.
Mit der Formatierung:
Bearbeiten: gibt jetzt die Farbe der Lösung zurück, die mir ein Semikolon ^^ erspart
quelle
Befunge ,
197368696754 Bytes(Ja, ich spiele Reverse Code Golf, je mehr Bytes desto besser)
Ich dachte, es könnte eine Herausforderung sein, diesen Algorithmus in Befunge zu schreiben, und es könnte Spaß machen
Ich möchte, dass es sich um ein Community-Programm handelt. Wenn also jemand daran arbeiten möchte, tun Sie dies bitte.Am Ende habe ich alles alleine gemacht, also werde ich alleine fertig (es ist fast fertig)
Was ist schon erledigt: ein trollförmiger Code
(Ja, es ist ein Troll, glaub mir)
Grundsätzlich liest es ein Array und berechnet die auszuführende Bewegung, um die Zeilen zu lösen, wenn eine Eingabe wie folgt erfolgt
(Das gesamte Array wird als Liste übergeben [Zeile1, Zeile2, Zeile3,…])
Ausgabe ist
Zeilen und Spalten beginnen beide bei 0.
Nun, da die Reihen gelöst sind, ist es fast geschafft! Hurra!
Erläuterung: (wird später aktualisiert)
Es gibt also 5 Hauptteile:
Graue Teile sind Initialisierungen
Hier ist eine tiefere Erklärung des Moduls, das die zu kombinierenden to-Boxen findet (was hier übrigens codiert ist).
Der CALL-Teil ist, wenn der Befehlszeiger auf ein anderes Modul zeigt, um es zu Boxen zu kombinieren. Über den Eintrag 'B' gelangt man zu diesem Modul zurück
Hier ist ein Pseudocode: (currentx bezieht sich auf das Lesen des Arrays) Für:
Beachten Sie, dass Sie, wenn Sie es testen möchten, nachgestellte Leerzeichen und neue Zeilen einfügen müssen, damit genügend Speicherplatz für das Array vorhanden ist, wenn Sie das von mir verknüpfte Interpret verwenden möchten . 22 + die Anzahl der Zeilen in der Eingabe als abschließende Zeilen und 34 + die Anzahl der Spalten als abschließende Leerzeichen in einer Zeile sollten in Ordnung sein.
quelle
\r\n
statt\n
nur gezählt?)C 404 Bytes
Mein erster Code Golf, ich bin ziemlich zufrieden mit dem Ergebnis. Hat aber viel zu lange gedauert. Es ist nicht das Standard-C, sondern alles, was unter gcc ohne spezielle Flags kompiliert wird (und Warnungen ignoriert). Es gibt also eine verschachtelte Funktion. Die Funktion verwendet
f
die Dimensionenm
undn
als erstes Argument und als drittes Argument einen (int-Zeiger) auf ein Array der Größem
×n
(zuerst durch Zeilen indiziert). Die anderen Argumente sind Dummy-Argumente. Sie müssen nicht übergeben werden. Sie dienen nur dazu, Byte beim Deklarieren von Variablen zu sparen. Jedes geänderte Paar wird im Format in STDOUT geschriebenrow1,col1:row1,col1;
, wobei die Paare durch ein Semikolon getrennt werden. Verwendet eine 0-basierte Indizierung.Ich habe einen etwas anderen Algorithmus als OP zum Lösen einzelner Zeilen / Spalten verwendet. Es geht ungefähr so (Pseudocode):
Die
for(;~b;b--)
Schleife wird genau zweimal ausgeführt und löst beim zweiten Durchgang Spalten anstelle von Zeilen. Dies geschieht durch Vertauschenn
undm
Ändern der Werte vono
und,p
die in der Zeigerarithmetik zur Adressierung des Arrays verwendet werden.Hier ist eine Version, die mit einem Test-Main ungolfed ist und das gesamte Array nach jeder Bewegung druckt (drücken Sie die Eingabetaste, um Schritt 1 zu machen):
quelle