Pyth ist eine auf Python basierende Golfsprache . Es wird die Präfixnotation verwendet, wobei jeder Befehl eine andere Arität hat (Anzahl der akzeptierten Argumente).
Ihre Aufgabe ist es, einen Syntax-Checker für eine (nicht existierende) Pyth-ähnliche Sprache, Pith, zu schreiben.
Markensyntax
Pith hat nur 8 Single-Char-Befehle:
01234()"
01234
Jeder hat die Arität der entsprechenden Zahl und erwartet daher viele Argumente danach. Beispielsweise,
400010
ist ein korrektes Pith-Programm, da 4
auf dieses vier Argumente folgen 0
0
0
und auf 10
das letzte ein 1
einzelnes Argument folgt 0
. Um dies zu veranschaulichen, können wir uns den folgenden Baum ansehen:
R
|
4
|
-------------
| | | |
0 0 0 1
|
0
wo R
ist der Wurzelknoten. Eine alternative Möglichkeit, dies zu überdenken, besteht darin, dass sich jede Zahl auf die Anzahl der untergeordneten Knoten im obigen Baum bezieht.
Hier ist ein weiteres gültiges Pith-Programm mit mehr als einem Basisbefehl:
210010
korrespondierend zu
R
|
-------------
| |
2 1
| |
--------- 0
| |
1 0
|
0
Auf der anderen Seite,
3120102100
ist kein korrektes Pith-Programm, da die Initiale 3
nur zwei Argumente enthält, die wir anhand des folgenden Baums erkennen können:
R
|
3
|
------------------------ ??
| |
1 2
| |
2 ------
| | |
------ 1 0
| | |
0 1 0
|
0
Als nächstes (
beginnt eine unbegrenzte und )
endet eine unbegrenzte. Ein unbegrenztes Argument akzeptiert eine beliebige Anzahl von Argumenten (gierig) und zählt als ein einziges Argument für jeden übergeordneten Befehl. Am Ende des Programms noch offene unbegrenzte Karten werden automatisch geschlossen. Ein )
Befehl ist kein Fehler, wenn keine unbegrenzten Möglichkeiten offen sind - er führt einfach nichts aus. *
Zum Beispiel das Mark-Programm
)31(0)0(201000100
entspricht dem Baum
R
|
3
|
------------------------------
| | |
1 0 (
| |
( -----------------------------
| | | | | |
0 2 0 0 1 0
| |
------- 0
| |
0 1
|
0
Leere unbegrenzte Felder sind in Ordnung, ebenso ()
ein gültiges Pith-Programm.
Ein ungültiges Pith-Programm mit einem unbegrenzten ist
12(010
da 2
bekommt der nur ein argument (das unbegrenzte).
Schließlich "
beginnt und endet ein String, der immer 0 ist und als einzelnes Argument zählt, z
2"010""44)()4"
Das ist nur ein 2
Wesen, dem zwei String-Argumente übergeben werden "010"
und "44)()4"
. Wie unbegrenzte Zeichenfolgen können auch Zeichenfolgen leer sein, und nicht geschlossene Zeichenfolgen am Ende des Programms werden automatisch geschlossen.
* Dieser Teil unterscheidet sich von dem ursprünglichen Pyth, der in einem Fall wie dem Beenden der 1-Arität und dem Auslösen eines Fehlers tatsächlich etwas tut1)
.
Input-Output
Die Eingabe ist eine einzelne nicht leere Zeichenfolge, die nur aus den Zeichen besteht 01234()"
. Optional können Sie davon ausgehen, dass immer eine zusätzliche nachgestellte Zeile vorhanden ist. Sie können eine Funktion oder ein vollständiges Programm für diese Herausforderung schreiben.
Sie sollten einen Wahrheitswert ausgeben, wenn die Eingabe syntaktisch gültig ist, oder einen falschen Wert, wenn dies nicht der Fall ist. Die Wahrheits- und Falschheitswerte müssen festgelegt werden, damit Sie nicht 1
für ein gültiges Programm und 2
für ein anderes ausgeben können .
Wertung
Das ist Code-Golf, also gewinnt der Code mit den wenigsten Bytes.
Testfälle
Wahrheit:
0
)
(
"
()
""
10
400010
210010
("")00
3"""""
(0)))0)1)0
2(2(2(0)0)0)0
2"010""44)()4"
)31(0)0(201000100
())2)1))0"3())"))
3("4321("301(0)21100"4")"123"00)40"121"31000""01010
Falsch:
1
1(310
(1)0)
12(010
4"00010"
3120102100
20(2((0)(0)))
2(2(2(0)0)0)01)
4(0102)00)00000
2"00"("00"2(""))
quelle
[( [2 [0] [1 [0] ] ] [0] [1 [0]] [0] ]
? Der eine hat Zweige von 2, 0, 0, 1 und 0 - der zweite sollte nicht da sein.())2)1))0"3())"))
(was meiner Meinung nach zutreffen sollte).()210""
mit vielen No-Ops ist)Antworten:
CJam, 65 Bytes
Meine Güte, ich wünschte, CJam hätte Regex, dies hätte dann in weniger als 50 Bytes abgeschlossen werden können
Die Hauptidee ist zu halten Sachen zu reduzieren ,
0
dh10
auf0
,200
um0
und so weiter. Sobald dies geschehen ist, reduzieren wir alle aufeinander abgestimmt Klammern0
, also()
zu0
,(0)
zu0
,(00)
zu0
und so weiter. Das wiederholen wir die ZykluszeitenL
, wobeiL
die Eingangslänge ist.Die Eingabezeichenfolge durchläuft anfangs eine zusätzliche Verarbeitung, bei der wir die Nichtübereinstimmung korrigieren
"
und viel hinzufügen, um die Nichtübereinstimmung)
zu kompensieren(
Dies stellt sicher, dass nach all den Iterationen nur
0
(und kein-op)
) in der Zeichenfolge übrig bleibt.Update - Fehler behoben, durch den
)
No- Ops der obersten Ebene als schädlich eingestuft wurdenCode-Erweiterung
Probieren Sie es hier online aus oder führen Sie die gesamte Suite aus
quelle
Regex, PCRE-Geschmack, 83 Bytes
Probieren Sie es hier aus.
Regex, PCRE-Geschmack, 85 Bytes
Probieren Sie es hier aus.
Habe einige Ideen in der Antwort von dan1111 verwendet .
Einige Erklärungen zu
(?2)*(()(?1))?
.quelle
(?2)*(()(?1))?
ist das letzte Puzzleteil, das ich gesucht habe. Nizza zu finden! ;)(?2)*(()(?1))?
Teil richtig verstehe ,(()(?1))?
stimmt das Teil nie mit etwas überein, da es(?2)*
bereits alles auffrisst, was(()(?1))?
passen kann, und dieses Konstrukt wird verwendet, um die Erfassungsgruppe 3(
festzulegen, wenn wir die Erfassungsgruppe 3 betreten, und()
um die Übereinstimmung zu ermöglichen ungepaart)
).Lex, 182 Bytes (157 w / Stapel fester Größe)
Für diese Programme muss die Eingabe eine einzelne Zeichenfolge mit Zeilenende und gültigen Zeichen sein.
Das obige Programm schlägt fehl, wenn nicht genügend Speicher vorhanden ist. Dies könnte theoretisch passieren, wenn Sie genügend Speicher zur Verfügung stellen
(
. Aber da ein Segfehler als Fehlschlag gilt, nehme ich das als "Fehlschlag", obwohl die Problembeschreibung nicht sagt, was zu tun ist, wenn die Ressourcen nicht ausreichen.Ich habe es auf 157 Bytes reduziert, indem ich nur einen Stapel mit fester Größe verwendet habe, aber das schien zu schummeln.
Kompilieren:
Prüfung:
Testausgang:
quelle
80386 Assembler, 97 Bytes
Hex-Dump:
Dies durchläuft die Eingabe einmal, wobei Zahlen größer als Null auf den Stapel geschrieben und dekrementiert werden, wenn eine Null verarbeitet wird. Ungebundene werden als -1 verarbeitet.
Funktionsprototyp (in C) (Funktion gibt 0 zurück, wenn ungültig und 1, wenn gültig):
Äquivalente Baugruppe (NASM):
Der folgende Code in C kann mit GCC auf einem POSIX-System zum Testen verwendet werden:
quelle
Python 2, 353 Bytes
Die Analysefunktion durchläuft die Token nacheinander und erstellt einen Baum der Programmstruktur. Ungültige Programme lösen eine Ausnahme aus, durch die eine Null (Falsy) gedruckt wird. Andernfalls führt eine erfolgreiche Analyse zu einer Eins.
Die Ausgabe der Tests zeigt die Parser-Ausgabe:
Der Code vor dem Minifier:
quelle
==
in den Tests vertauschen. Wenn Sie die Zeichenfolgen an die erste Stelle setzen, können Sie dies tunif')'==q
. Ich glaube, eine derbreak
Aussagen könnte durch eine ersetzt werdenf=0
, da Sie dadurchwhile f
genauso gut aus der Schleife geraten . Schließlich stattassert x==y
können Sie verwenden1/(x==y)
für eineZeroDivisionError
. ;)Pip ,
88-72BytesIdee aus Optimizers CJam . Mein ursprünglicher Versuch, das Problem mit einem rekursiven Abstiegsparser zu lösen, war ... etwas länger.
Formatiert mit Erklärung:
Interessante Tricks:
0X,5
ist es zum Beispiel0 X [0 1 2 3 4] == ["" "0" "00" "000" "0000"]
.R
Ternary-Eplace-Operator eine Liste aller seiner Argumente erstellen:"abracadabra" R ["br" "ca"] 'b
givesababdaba
, zum Beispiel. Ich nutze dieses Featurez
hier gut aus.""
, die leere Liste[]
und jeder Skalar, der Null ist. Also0
ist falsch, aber auch0.0
und"0000000"
. Diese Funktion ist manchmal unpraktisch (um zu testen, ob eine Zeichenfolge leer ist, muss ihre Länge getestet werden, da sie ebenfalls"0"
falsch ist), aber für dieses Problem ist sie perfekt.quelle
Javascript (ES6),
289288285282278244241230 Bytesquelle