Hintergrund
In Bejeweled- und ähnlichen Spielen muss der Spieler zwei benachbarte Edelsteine (keine Diagonalen) in einem 8x8-Raster von Edelsteinen tauschen, um drei gleiche Farben in einer Reihe zu finden. Die Edelsteine können horizontal oder vertikal angepasst werden. Das Spiel wird fortgesetzt, bis es keinen Zug mehr gibt, der in drei aufeinanderfolgenden Zügen ausgeführt werden kann. Zu diesem Zeitpunkt ist das Spiel beendet.
Aufgabe
Ziel ist es, ein Programm zu schreiben, das feststellt, ob ein Bejeweled-Spiel noch nicht beendet ist. Mit anderen Worten, es muss überprüft werden, ob es einen möglichen Zug gibt, der mindestens drei in einer Reihe macht. Es können mehr als drei Edelsteine hintereinander sein und es ist immer noch ein gültiger Zug.
Eingang
Ihr Programm muss über die Standardeingabe eine 8x8-Darstellung eines Bejeweled-Gitters akzeptieren. Jede der sieben Schmucksteinfarben wird durch eine Ziffer von 1 bis 7 dargestellt. Jede Zeile enthält eine Zeile, und es werden 8 Zeilen mit jeweils 8 Ziffern eingegeben. Siehe die Beispiele. Sie können davon ausgehen, dass die Eingabe immer diesem Format folgt und niemals bereits drei hintereinander enthält.
Ausgabe
Das Programm muss dann (auf Standardausgabe) ausgeben yes
oder no
abhängig davon, ob mindestens ein gültiger Zug vorhanden ist oder nicht, der drei oder mehr Edelsteine in einer Reihe ergeben würde. Ihr Programm darf nichts anderes als eine einzelne Instanz von entweder yes
oder ausgeben no
.
Regeln
Ihr Programm darf keine externen Dateien oder Ressourcen oder Befehlszeilenargumente verwenden oder einen bestimmten Dateinamen erfordern. Das Programm mit der geringsten Anzahl von Bytes im Quellcode gewinnt.
Beispiele
Eingang:
12314131
13224145
54762673
61716653
61341144
23453774
27645426
75575656
Ausgabe: yes
Eingang:
35261546
76421754
15743271
62135642
35617653
64565476
54427254
15635465
Ausgabe: no
Antworten:
Ursprüngliche Lösung: JavaScript -
261255228227179153 ZeichenAngenommen, die zu testende Zeichenfolge befindet sich in der Variablen
s
(um sie zu einer Funktion zu machen,f
fügen Sief=s=>
sie am Anfang des Codes hinzu oder nehmen Sie andernfalls die Eingabe von einer Eingabeaufforderung und ersetzen Sie sies
durchprompt()
).Ausgänge ist an die Konsole.
3 rd Lösung: JavaScript (ECMAScript 6) - 178 Zeichen
Ich habe die zweite Lösung (die reguläre Ausdrücke verwendet, um in bestimmten Konfigurationen nach Zeichen zu suchen) verwendet und sie überarbeitet, um nur die Zeichenfolge auf identische Zeichen in denselben Konfigurationen zu überprüfen, ohne reguläre Ausdrücke zu verwenden.
Die Base-36-Zeichenfolge
"2313ab1b8a2a78188h9haj9j8iaiir9r"
gibt zu überprüfende Versatzpaare an, dh das Paar23
führt zu der Prüfung, ob i te Zeichen mit dem (i + 2) -ten Zeichen und dem (i + 3) -ten Zeichen (das Äquivalent des regulären Ausdrucks ) identisch ist(.).\1\1
- mit einigen zusätzlichen Überprüfungen, um sicherzustellen, dass das nicht identische Zeichen kein Zeilenvorschub ist).2 nd Lösung: JavaScript (ECMAScript 6) - 204 Zeichen
Erstellt mehrere reguläre Ausdrücke (siehe unten für weitere Details) unter Verwendung von Wertepaaren aus der Base-18-Zeichenfolge
10907160789879h8
und führtOR
die Tests durch. Um es weiter zu reduzieren, können Sie feststellen, dass die regulären Ausdrücke paarweise vorkommen, wobei einer der "umgekehrten" Ausdrücke des anderen ist. wenn Sie diese Tests wieder in den Anhang0088
der Base-18-Zeichenfolge einfügen möchten ).Erläuterung
Beginnen Sie mit 16 regulären Ausdrücken, die alle möglichen Konfigurationen gültiger Züge abdecken:
( Anmerkung: der regexs für 3-in-einer-Reihe horizontal (0 - ten ) und vertikal (Teil der 9 th ) ist irrelevant , da die Zustände OP dass diese zusammenpassenden Eingänge nie vorhanden sein. )
Wenn Sie jeden dieser Parameter anhand der Eingabe testen, wird festgestellt, ob ein gültiger Zug dieser Konfiguration gefunden werden kann.
Die regulären Ausdrücke können jedoch zu folgenden 6 kombiniert werden:
Diese können dann zu einem einzigen regulären Ausdruck kombiniert werden:
Welche muss nur gegen den Eingang getestet werden.
Testfälle
Einige Testfälle, die für andere nützlich sein könnten (entspricht nicht dem Eingabeformat, nur die Ziffern 1-7 zu verwenden, ist aber leicht zu korrigieren und nur ein 8x4-Raster), da dies das Minimum ist, das für einen Test aller gültigen Eingaben erforderlich ist ).
Im Format einer Zuordnung von Eingabezeichenfolge zu dem der 16 regulären Ausdrücke darüber entspricht.
Bearbeiten 1
Ersetzen Sie
\d
s durch.
- Speichert 6 Zeichen.Bearbeiten 2
Ersetzen Sie
(?:.|\n)
mit[\s\S]
und entfernt zusätzliche nicht-einfangenden Gruppen und aktualisiert Rückverweise (wie vorgeschlagen m-Buettner ) und in Ja / Nein - Ausgang hinzugefügt.Bearbeiten 3
Bearbeiten 4
Eine weitere (kürzere) Lösung und zwei weitere nicht übereinstimmende Testfälle wurden hinzugefügt.
Bearbeiten 5
Bearbeiten 6
quelle
?'yes':'no'
Anzahl deiner Charaktere an, um Fairness zu gewährleisten, da sie in den Anforderungen enthalten ist und von allen anderen verwendet wird..
Zeichen, einschließlich Zeilenvorschub? In Perl besteht die kombinierte Regexp aus einer Zeichenfolge von nur 129 Byte (was ich, da ich faul bin, mit Regexp :: Assemble kompiliert habe ), sodass das gesamte Perl-Programm ungefähr 150 Byte umfasst..{8}|.{9}
mit.{8,9}
und.{7}|.{8}
mit ersetzen.{7,8}
Python 383
Nur eine einzige * Zeile Python!
* Nun, mit Semikolons, aber das ist in Python immer noch nicht trivial (Python-Einzeiler machen Spaß! )
quelle
Node.js - Naive Lösung - 905 Byte
Nun, noch keine Antworten, also werde ich eine wirklich naive Lösung in Node.js posten
Es durchläuft jede mögliche Bewegung und testet dann das resultierende Brett, um festzustellen, ob es 3 in einer Reihe gibt.
Golfen (mit Google Closure Compiler) (einige hacky Sachen drin wie! 0 und! 1; ich bin mir nicht mal sicher, was es mit meinem XOR-Swap gemacht hat)
Beachten Sie, dass ich das alles auf meinem Handy geschrieben habe und keine Zeit habe, es zu testen oder so. Kommentar, wenn Sie Fehler sehen, werde ich es später selbst überprüfen.
Die für Menschen lesbare Version vor dem Golf
quelle
Perl,
11496959392878685 BytesBeinhaltet + für
-a0p
Führen Sie mit der Eingabe auf STDIN aus:
bejeweled.pl
:Dies kombiniert eine horizontale Regex-Lösung in einer Richtung mit Rotationen
Erläuterung:
In dieser Lösung werde ich wiederholt drehen und die folgenden 4 Tests durchführen:
Wo
\C
ist "ein beliebiges Zeichen" (anders als.
Newline). Abgesehen davon, dass dies\C
veraltet ist und zu Warnungen führt, verwende ich\H
stattdessen (nicht horizontales Leerzeichen), was gut genug ist, um alle Ziffern und Zeilenumbrüche zu erfassen.Nach 4 Umdrehungen hat dies alle 16 erforderlichen Tests durchgeführt
quelle
Python3, 314B
Ändern Sie die 8, die 5 in Zeile 6 und die 8 in Zeile 9, um beliebig große Eingabegrößen zu verarbeiten. ist es auch egal, was jeder Wert ist, also können Sie ihn füttern:
und es wird zurückkehren
yes
.Anmerkungen
quelle
GNU sed 255 + 2 = 257B
Ich dachte, dass dies nicht so gut wie Python sein würde, aber es ist jetzt: - / Ich war heute ohne Internetzugang, also habe ich mich damit beschäftigt, dies in sed zu lösen :). Muss mit dem -r-Flag aufgerufen werden, dh
sed -rf command.sed < input
ich habe 2 zu meiner Punktzahl hinzugefügt.Wie es funktioniert:
quelle
Ruby, 201 Bytes
Ich war enttäuscht, keine Lösungen für diese großartige Herausforderung zu sehen, die weder Regex noch rohe Gewalt anwenden (obwohl diese großartig sind), also schrieb ich eine. Es werden Eingaben über STDIN vorgenommen.
Der bitweise arithmetische Kernalgorithmus leitet sich aus dieser fantastischen Antwort von @leander auf Game Development Stack Exchange ab.
Ruby Lambda, 181 Bytes
Hier ist es als Lambda, das eine Zeichenfolge nimmt und zurückgibt
true
oderfalse
:Siehe es auf repl.it: https://repl.it/ColJ/2
Ungolfed & Erklärung
Der Code durchläuft die Ziffern "1" bis "9". Jede Iteration hat zwei diskrete Schritte:
Der erste Schritt ist die Board-Transformation, die Sie im
s.scan(n)
Block im ungolfed Code sehen können. Es wandelt die Karte in ein Array von 8 Ganzzahlen um, eine für jede Zeile, indem übereinstimmende Ziffern als 1 und alle anderen als 0 in einer binären Zeichenfolge behandelt werden. Nehmen Sie zum Beispiel die Reihe12231123
. In der ersten Iteration wird dies die Binärzeichenfolge10001100
(alle Einsen werden zu - äh, bleiben - Einsen und alle anderen Ziffern werden zu Nullen). Dies ist die Dezimalzahl 140. In der zweiten Iteration wird dieselbe Zeile01100010
(alle Zweisen werden zu Zweisen und Alle anderen Ziffern werden zu Nullen oder zu Dezimalzahlen von 98.Gleichzeitig wird eine zweite Transformation ausgeführt, die mit der ersten identisch ist, wobei jedoch die Platine um 90 Grad gedreht wird. Auf diese Weise können wir die gleiche Logik für horizontale und vertikale Übereinstimmungen verwenden. Der Einfachheit halber werden die beiden Karten zu einer einzigen langen Karte mit einer Null am Anfang, in der Mitte (um die beiden Karten zu trennen) und dem Ende zum Auffüllen zusammengefügt.
Der zweite Schritt ist die Suche nach möglichen Übereinstimmungen, die Sie im
each_cons(3).any?
Block sehen können. Die transformierten Zeilen (die jetzt 8-Bit-Ganzzahlen sind) werden in (überlappenden) Gruppen von drei Zeilen ( x , y , z ) unter Verwendung von bitweiser Arithmetik überprüft . Jede Gruppe wird überprüft, um festzustellen, ob eine Übereinstimmung in Reihe y hergestellt werden kann , entweder durch Verschieben eines Stücks in Reihe y oder durch Verschieben eines Stücks in y von x oder z . Da vor und nach der ursprünglichen und der gedrehten Brettreihe eine Null "Reihe" vorhanden ist, müssen wir nicht prüfen, ob wir in der ersten oder letzten Reihe eines Brettes sind.Wenn keine Übereinstimmungen gefunden wurden, wird mit der nächsten Iteration fortgefahren.
quelle