Golf ein lila Dolmetscher
Lila ist ein Esolang, der zwei Hauptzwecken dient:
- Eine Minimierung der Aubergine , da es nicht genug selbstmodifizierende Einzelanweisungssprachen gibt.
- Die Möglichkeit erschreckend kleiner Golfdolmetscher zuzugeben. Mein erster Durchgang bei einem einigermaßen voll ausgestatteten Python 2-Interpreter ist nur 702 Bytes, und ich bin sicher, ein erfahrener Golfer könnte sich einiges davon abschneiden.
Ihr Ziel ist es, einen Dolmetscher für diese Sprache zu schreiben.
Informationen zu Lila:
Ein Purple-Programm ist eine Folge von Zeichen, die in einem unendlichen, adressierbaren Speicherfeld so angeordnet sind, dass das erste Zeichen des Programms an der Adresse Null steht. Der Rest des Arrays (vor und nach dem Speichern des Purple-Programms) wird auf Null initialisiert.
In Purple gibt es drei Register mit den Bezeichnungen a und b und i , von denen jedes eine Ganzzahl mit Vorzeichen enthalten kann und auf Null initialisiert ist. ich ist auch der Befehlszeiger und zeigt immer auf den gerade ausgeführten Purple-Befehl.
In jedem Zyklus liest der Interpreter eine Folge von drei aufeinander folgenden Zeichen, beginnend an der durch den Befehlszeiger angegebenen Speicherstelle, und versucht, diese Folge als den Purple-Befehl auszuführen. Danach wird der Anweisungszeiger immer um 3 erhöht.
Syntaktisch besteht der Purple-Befehl aus drei Zeichen (oder Codierungen davon) in einer Reihe, wie " xyz ".
Das erste Zeichen x kann eines der folgenden sein:
abABio
Diese Symbole haben folgende Bedeutung:
a - Place the result in register a.
b - Place the result in register b.
A - Place the result in the location in memory referred to by register a.
B - Place the result in the location in memory referred to by register b.
i - Set the instruction pointer to the result.
o - Output the result to stdout.
Die anderen zwei Bytes y und z können eines der folgenden sein:
abABio1
Jedes dieser Symbole hat folgende Bedeutung:
a - Return the contents of register a.
b - Return the contents of register b.
A - Return the contents of the memory array at the address stored in register a.
B - Return the contents of the memory array at the address stored in register b.
i - Return the contents of register i (the instruction pointer).
o - Return the value of a single character read from stdin.
1 - Return the literal numeric value 1.
Nach dem Abrufen der Anweisung wertet der Purple-Interpreter y und dann z aus , subtrahiert das Ergebnis von z vom Ergebnis von y und führt dann die durch x angegebene Aktion für die Differenz aus.
Wenn die Folge von drei Zeichen (oder deren Codierungen) keine gültige Purple-Anweisung ist, wird der Interpreter sofort angehalten, ohne dass Fehler auftreten.
Ihr Dolmetscher muss:
- Sei ein komplettes Programm, keine Funktion.
- Niemals nach stderr ausgeben, es sei denn, EOF wird gelesen .
- Verhalten Sie sich bei allen wohlgeformten Eingaben, die keine sehr großen Zahlen enthalten, einschließlich der unten angegebenen Testprogramme, identisch zur Referenzimplementierung. (Naja, genau wie beim Timing - es kann langsamer laufen, aber nicht zu viel!)
Sie können das Programm dem Interpreter in einer beliebigen Form zur Verfügung stellen: Lesen Sie es aus einer Datei, binden Sie es als Zeichenfolge in das Programm ein oder lesen Sie es aus stdin.
Testfälle:
Das Programm
ooo
wenn mit Eingabe ausgeführt
z!
sollte nachgeben
Y
Das Programm
bbboobiii
wenn mit Eingabe ausgeführt
It's a cat program.
(oder eine andere Eingabe) sollte ergeben
It's a cat program.
(oder was auch immer Eingang es erhielt) und dann von vorne anfangen und das gleiche noch einmal tun .
Das Programm
Aoab11bi1bABoAaiba
wenn mit Eingabe ausgeführt
0
sollte nachgeben
0
und dann halt, aber bei lauf mit eingabe
1
sollte weiterhin ausgeben
1
für immer.
Das Programm
b1bbb1oAbabaa1ab1Ab1Bi1b
sollte nachgeben
b1bbb1oAbabaa1ab1Ab1Bi1b
Das Programm
aA1aa1bb1oAbbi1bb1bbAb1Bi1b Purple is the awesomest! Why haven't you tried it yet?
!dlroW ,olleG
sollte nachgeben
Hello, World!
Wertung:
Dies ist Code-Golf , also gewinnt die kürzeste Quelle in Bytes, die möglicherweise durch den folgenden Bonus modifiziert wird.
Bonus:
- -10%, wenn Ihr Interpreter einen Dateinamen entweder von stdin oder von einem Befehlszeilenargument liest und das Programm aus der Datei lädt.
quelle
uint32
für Zeichen und MAXINT für intsAntworten:
Pyth,
148128121 Bytes (oder 124 * .9 = 111,6, siehe unten)Testsuite
Code in der ersten Zeile von STDIN, Eingabe in das Purple-Programm für den Rest von STDIN. Um Code mit Zeilenumbrüchen zu verwenden, verwenden Sie die alternative Version unten.
Vernünftig golfen. Hier ist es mit Zeilenumbrüchen und Einrückung für Klarheit:
Grundsätzlich führt eine
#
Schleife die Ausführung und das Anhalten über eine Fehlerunterbrechung aus.a
undb
werden zu einer einzigen Variablen zusammengefasstJ
.Z
ist der Befehlszeiger.k
wird in das Purple-Programm eingegeben.H
ist das Band, dargestellt als Wörterbuch.b
ist das aktuelle Ergebnis.Y
ist das aktuelle erste Byte der Anweisung.Lesen aus der Datei:
Geben Sie den Dateinamen als erste Zeile von STDIN an. Testlauf:
quelle
JavaScript (ES6), 292 Byte
Erläuterung
JavaScript-Antworten sind immer komisch, wenn
STDIN
undSTDOUT
werden benötigt ...Die erste Eingabeaufforderung ist die Eingabe für die Programmzeichenfolge. Jede Eingabeaufforderung, die sich aus einer
o
Anweisung ergibt , liest nur das erste Zeichen.eval
wird verwendet, um einen allgemeinen Ausdruck zu ersetzen, der einige Bytes spart. Ungolfed und ohne daseval
sieht das Programm so aus:quelle
c="charCodeAt"
mit nur ersetzt werdenc
?array[-1] = 1
ist das gleiche wiearray = { "-1": 1 }
. Beides erreichen Sie mitarray[-1]
.Ceylon,
827792671 BytesEs verhält sich ein bisschen anders als die Referenzimplementierung, wenn das Programm versucht, Eingaben bei EOF zu lesen. Die Referenzimplementierung stürzt mit einem TypeError ab, der zu teuer ist, um hier reproduziert zu werden (und wahrscheinlich auch mit einem Fehler), sodass stattdessen -1 zurückgegeben wird ( wiederholt, falls erforderlich).
(Wenn versucht wird, -1 nach stdout zu schreiben, wird der Interpreter jedoch mit einem OverflowError beendet. Ähnliches passiert, wenn eine Ganzzahl außerhalb des Unicode-Bereichs ausgegeben wird.)
Der Interpreter verwendet das Programm als erstes Befehlszeilenargument (stellen Sie sicher, dass Sie es für Ihre Shell in Anführungszeichen setzen, wenn es Leerzeichen oder andere interessante Dinge enthält).
In Ceylon können wir Eingaben nur leicht zeilenweise lesen (ich denke, dies wird sich in einer der nächsten Versionen ändern). Wenn
o
also zum Lesen verwendet wird, lese ich eine ganze Zeile und puffere die Teile für zukünftige Zwecke. Ich denke, es funktioniert ähnlich in der Python-Implementierung, wenn Sie mit einem Terminal verbunden sind.Wenn Sie versuchen, einen Befehl (Teil) auszuführen, der nicht zu den gültigen Zeichen gehört, wird der Befehl
nothing
wird ein AssertionError ausgelöst, den wir dann im catch-Block um die Hauptschleife abfangen.Ich denke, dies sollte vorzugsweise ein benutzerdefinierter Ausnahmetyp sein (da AssertionError auch an anderen Stellen auftreten kann, wenn ich einen Fehler habe), aber das würde viel mehr Platz in Anspruch nehmen und die meisten Verbesserungen, die ich gegenüber der ersten Version gemacht habe, verschlingen.
Einige Tricks zum Golfen:
map
Funktion erstellt wurde, und erstellen jedes Mal eine neueA
oder sieB
wird als x verwendet .variable
Anmerkung, die jetzt istl
).E
(für die Umgebung) und dies
(Schritt) -Methode entfernt - alles passiert jetzt innerhalb derrun
Funktion..integer
zum Abrufen des Codepunkts eines Zeichens zu verwenden, erhalten Sie.hash
dasselbe Ergebnis. Sostring*.hash
ist das gleiche wiestring.map(Character.integer)
(gibt einen Iterationswert der Codepunkte aus einer Zeichenfolge an).is I ...
ist er kürzer alsexists ...
.x
) in eine Zeichenfolge konvertieren ,"``t``"
ist es kürzer alst.string
(oder was ich für ein Zeichen verwendet habeString{t}
).Hier ist die formatierte (und kommentierte) Version:
quelle