Dies ist natürlich die richtige Sprache für die Aufgabe. : ^ D
s:({c<L>}{c<R>}0[(<R> <L>)(<L> <R>)_?])%{30}
c:0 *$
Entspricht der gesamten Eingabe, wenn es sich um eine gültige Schlange handelt. stimmt nicht überein, wenn dies nicht der Fall ist. Probieren Sie es hier aus!
Erläuterung
SnakeEx ist eine 2-D-Pattern-Matching-Sprache . Ein Programm besteht aus einer Liste von Definitionen für "Schlangen", die die eingegebenen übereinstimmenden Zeichen durchsuchen, die Richtung ändern und andere Schlangen erzeugen. In unserem Programm definieren wir zwei Schlangen s
und c
.
Wir fangen damit an, c
weil es einfacher ist. Die Definition ist 0 *$
, was gut lesbar sein sollte, wenn Sie Regex kennen: match 0
, gefolgt von null oder mehr Leerzeichen, gefolgt von der Kante des Gitters. Das Wichtigste dabei: Dieses Matching kann in jede Richtung gehen. Wir werden c
sowohl aufwärts als auch abwärts von der Schlange aus verwenden, um zu überprüfen, ob 0
in jeder Spalte keine zusätzlichen s enthalten sind.
Nun zur Hauptschlange s
. Es hat die Form (...)%{30}
, was bedeutet, dass "der Inhalt der Klammern 30-mal übereinstimmt" - einmal für jeden 0
in der Schlange. So weit, ist es gut. Was steht in Klammern?
{c<L>}
Dies bringt eine neue c
Schlange hervor, die um 90 Grad nach links gedreht wurde. Die Richtung ist relativ zur Richtung der s
Schlange, sodass sich die neue Schlange nach oben im Gitter bewegt (die Hauptschlange bewegt sich nach rechts). Die c
Schlange überprüft, ob die aktuelle Gitterzelle eine ist 0
und ob jede Zelle darüber ein Leerzeichen ist. Wenn dies fehlschlägt, schlägt die gesamte Übereinstimmung fehl. Wenn es gelingt, machen wir weiter
{c<R>}
was dasselbe tut, nur nach rechts gedreht (zum unteren Rand des Gitters).
Beachten Sie, dass diese Spawns die Position des Matchzeigers in der Hauptschlange nicht beeinflussen. Sie sind ein bisschen wie Lookaheads in Regex. (Vielleicht können wir sie hier als "Lookbesides" bezeichnen?) Nachdem wir überprüft haben, dass wir auf a zeigen 0
und der Rest der Spalte nur Leerzeichen enthält, müssen wir tatsächlich die 0
folgenden Kriterien erfüllen :
0
Jetzt befindet sich der Übereinstimmungszeiger auf dem Zeichen rechts von der 0
. Wir müssen drei verschiedene Optionen ankreuzen: die Schlangenwinkel nach unten, die Schlangenwinkel nach oben oder die Schlange geht geradeaus. Hierfür können wir einen OR-Ausdruck verwenden:
[...]
In unserem OP haben wir drei Möglichkeiten:
(<R> <L>)
Drehe dich nach rechts, finde ein Feld und drehe dich erneut nach links (Schlangenwinkel nach unten).
(<L> <R>)
Drehe dich nach links, finde ein Feld und drehe dich erneut nach rechts (Schlangenwinkel nach oben).
_?
Stimmen Sie mit 0 oder 1 Unterstrichen überein. Da die Eingabe keine Unterstriche enthält, handelt es sich immer um eine leere Übereinstimmung (Snake geht geradeaus).
Nachdem Sie eine der drei oben genannten Optionen ausgewählt haben, sollte der Übereinstimmungszeiger 0
auf die nächste Spalte zeigen, damit der Ausdruck in Klammern erneut übereinstimmt.