Dies ist die wöchentliche Herausforderung Nr. 2. Thema: Übersetzung
Schreiben Sie ein Programm oder eine Funktion, die Quellcode für ein Programm in Prelude und Code für ein gleichwertiges Programm in Befunge-93 ausgibt . Damit das Programm äquivalent ist, sollte es für eine bestimmte Eingabe dieselbe Ausgabe wie das Prelude-Programm erzeugen und nur dann anhalten, wenn das Prelude-Programm anhält.
Eingabesprache: Prelude
Python-Interpreter:
Ein Prelude-Programm besteht aus mehreren "Stimmen", die gleichzeitig Befehle ausführen. Die Anweisungen für jede Stimme befinden sich in einer separaten Zeile. Jede Stimme hat einen separaten Stapel, der mit einer unendlichen Anzahl von Nullen initialisiert wird. Die Ausführung beginnt in der äußersten linken Spalte und rückt mit jedem Häkchen eine Spalte nach rechts vor, es sei denn, dies wird durch )
oder beeinflusst(
Anweisungen beeinflusst. Das Programm wird beendet, wenn die letzte Spalte erreicht ist.
Vorspezifikation für diese Herausforderung:
Digits 0-9 Push onto the stack a number from 0 to 9. Only single-digit
numeric literals can be used.
^ Push onto the stack the top value of the stack of the above
voice.
v Push onto the stack the top value of the stack of the below
voice.
# Remove the top value from the stack.
+ Pop the top two integers from the stack and push their sum.
- Pop the top two integers from the stack, subtract the topmost
from the second, and push the result.
( If the top of the stack is 0, jump to the column after the
matching `)` after the current column executes.
) If the top of the stack is not 0, jump to the column after
the matching `(` after the current column executes.
? Read an integer from STDIN.
! Pop one value from the stack and print it to STDOUT as an
integer.
<space> No-op
Anmerkungen
v
und^
agiere zyklisch, so dass diev
untere Stimme das Stack-Element der oberen Stimme und^
die obere Stimme die untere Stimme kopiert. Folgerung: Beidesv
und^
Duplizieren der Stapelspitze in einem einstimmigen Programm.- A
(
und seine Übereinstimmung)
können sich in verschiedenen Zeilen befinden. Allerdings , ein)
schaut immer auf dem Stapel der Stimme , wo die entsprechenden(
platziert wurde, nicht den Stapel , wo die)
selbst angeordnet ist. - Die von den Befehlen
^
und erzeugten Wertev
beziehen sich auf die Werte, die vor Abschluss aller anderen Vorgänge in derselben Spalte vorliegen. ?
und!
funktionieren anders als auf esolangs.org angegeben. Testen Sie daher unbedingt mit dem in diesem Beitrag bereitgestellten leicht geänderten Interpreter.
Input hat garantiert:
- Passende Klammern
- Nicht mehr als eine Klammer in einer Spalte
- Gleiche Anzahl von Zeichen in jeder Zeile
- Mindestens eine Zeile
- Keine Spalte mit mehr als einer E / A- Anweisung (
!
oder?
) - Ein Zeilenvorschubzeichen nach den Anweisungen für jede Stimme
- Keine anderen Zeichen als die oben genannten
Ausgabesprache: Befunge-93
Befunge ist eine stapelbasierte Sprache, deren Programmzähler (PC; Zeiger auf die aktuelle Anweisung) sich auf einem zweidimensionalen Raster frei bewegt. Es beginnt in der oberen linken Ecke und bewegt sich nach rechts. Das Spielfeld ist toroidal, dh die PC-Bewegung verläuft um beide Kanten. Befunge hat auch einen Stapel, der mit einer unendlichen Anzahl von Nullen initialisiert wird. Befunge hat folgende Operationen:
Sie können die folgenden Eigenschaften des Befunge-93-Compilers / -Interpreters annehmen:
- Ganzzahlen sind unbegrenzt genau.
- Es erlaubt Gitter jeder Größe.
- Gitterkoordinaten (für
g
undp
) basieren auf 0.
Wertung
Um zu verhindern, dass Einreichungen, die lediglich einen Prelude-Interpreter in Befunge erzeugen, die Prelude-Quelle fest codieren, wird das Ziel darin bestehen, die Größe des resultierenden Befunge-Quellcodes zu minimieren.
Im Folgenden finden Sie eine Reihe von Prelude-Programmen. Ihr Übersetzer wird auf all diesen ausgeführt. Ihre Punktzahl ist die Summe der Größen der Befunge-Programme, sofern alle gültig sind.
Ihr Übersetzer sollte nicht speziell für diese Testfälle optimiert werden (z. B. durch Hardcodierung handgeschriebener Befunge-Programme für diese). Wenn ich eine Antwort vermute, behalte ich mir das Recht vor, Eingaben zu ändern oder zusätzliche zu erstellen.
Beispieleingaben
Drucken n-1
bis 0
:
?(1-^!)
Logisches UND:
? (0)
?(0 )
1 !
Logisches ODER:
? (0)
? (0)
1 1 !
Überprüfen Sie die Parität der Eingabe (dh Modulo 2) der nichtnegativen Zahl:
?(1-)
^ v
v1-^^-!
Quadrieren Sie die Eingabe:
^
^+ !
?(1-)
Gib die n- te Fibonacci-Zahl aus, wobei n = 0
0 und n = 1
1 entspricht:
0 v+v!
1 ^
?(1-)
Signum:
1) v # - !
vv (##^v^+)
?(# ^ ##
Division für nicht negative Eingänge:
1 (# 1) v # - 1+)
vv (##^v^+)
? v-(0 # ^ #
?
1+ 1-!
Natürlich muss Ihr Programm in allen Fällen dasselbe Verhalten aufweisen, auch wenn das Verhalten des Beispielprogramms für negative Zahlen nicht angegeben ist.
Schließlich sollte Ihr Übersetzer nicht unangemessen lang sein:
- Es muss in einem Stack Exchange-Post enthalten sein
- Auf einem typischen Desktop-Computer sollten die Beispieleingaben in weniger als 10 Minuten verarbeitet werden.
Beachten Sie, dass eine numerische Eingabe für Prelude oder Befunge als optionales Minuszeichen gefolgt von einer oder mehreren Dezimalstellen und einer neuen Zeile angegeben wird. Andere Eingaben sind undefiniertes Verhalten.
Sie können Ihren Übersetzer in jeder Sprache schreiben. Kürzester übersetzter Befunge-Code gewinnt.
Bestenliste
- Sp3000 : 16430 Byte
1
befindet sich in einer Schleife, daher darf er nicht gedrückt werden. Eine 0 kann aus der unendlichen Anzahl von Nullen entstehen, die auf den Stapeln beginnen.Antworten:
Python 3 wird später punkten
Laufen wie
py -3 prefunge.py <input filename> <output filename>
.Es war eine langsame Woche für mich, also langweilte ich mich endlich genug, um diese sechs Monate alte Frage anzugehen. Ich würde fragen, warum es niemand anders versucht hat, aber ich habe immer noch das Gefühl, dass das Debuggen mir weh tut (und wahrscheinlich gibt es immer noch Fehler, soweit ich weiß).
Die Frage enthält keinen Befunge-93-Interpreter, daher habe ich diesen verwendet , der sich geringfügig von der Spezifikation unterscheidet. Die zwei Hauptunterschiede sind:
Wenn in einer bestimmten Zeile des Programms kein Zeichen vorhanden ist, können Sie nicht in diese Zeile schreiben. Dies bedeutet , dass Sie mehrmals die Eingabetaste drücken müssen, um am Ende genügend Zeilenumbrüche einzufügen . Wenn Sie
NaN
s in der Ausgabe sehen, ist dies die wahrscheinlichste Ursache.Gitterzellen sind nicht auf Null vorinitialisiert - der Einfachheit halber habe ich einige Vorinitialisierungen in die Befunge-Ausgaben aufgenommen, da dies jedoch nicht erforderlich ist, kann ich sie entfernen, wenn ich mit dem Scoring beginne.
Das Kernlayout der Ausgabeprogramme lautet wie folgt:
Der Stapelspeicherplatz befindet sich außerhalb des Programms, daher der Kommentar zum Eingeben von Spam in der neuen Zeile aus früheren Versionen.
Die Kernidee ist, jeder Stimme eine Reihe zuzuweisen, die als Stapel dient. Um diese Stapel beizubehalten, haben wir auch eine spezielle Reihe mit Stapellängen, in der die Länge jedes Stapels in einer Zelle entlang der Reihe aufgezeichnet wird. Das Programm gibt dann viele
g
ets undp
uts aus, zB zum Ausdrucken des Prozesses ist:y = stack_row[stack], x = stack_length[stack]
.91+,
, dh drucken Sie als Ganzzahl und drucken Sie dann eine neue Zeilestack_length[stack]
Um die gleichzeitige Auswertung einer Spalte durchzuführen, werden alle erforderlichen Zellen gelesen und ihre Werte auf dem Stapel gehalten, bevor Zellen beschrieben werden (z. B. für das Druckbeispiel können zwischen dem ersten und dem zweiten Schritt mehr Anweisungen vorhanden sein).
`
Der Wert größer als wird verwendet, um sicherzustellen, dass die Stapellängen niemals negativ werden, und um Nullen zu setzen, wenn der Stapel leer ist. Hier kommt die deutlich sichtbare Verzweigung her, aber ich habe eine Idee, mit der die Verzweigung entfernt wird, wodurch viel Leerzeichen in der ersten und dritten Zeile entfernt werden sollten.Da Prelude-Schleifen in beide Richtungen springen können, verwenden wir für die Schleifen zwei Zeilen pro Schleife in einer Konfiguration wie der folgenden:
Diese Loops machen derzeit den größten Teil der Bytes aus, können jedoch leicht heruntergespielt werden, indem sie in der Codebox mit abgelegt werden
p
ich, nachdem ich froh bin, dass der Übersetzer richtig funktioniert.Hier ist ein Beispiel für die Ausgabe von
?(1-^!)
, dh Druckenn-1
auf0
:Square-the-Input:
Division (kleine Eingaben werden empfohlen):
Es gibt auch eine Reihe anderer kleinerer Optimierungen, die mir in den Sinn kommen, zum Beispiel das Ersetzen
07p07g
durch:07p
, aber ich mache diesen Schritt nach dem anderen :)quelle
Will score later
2 Jahre und es zählt! :)