Erstellen Sie einen Interpreter für eine gefälschte, stapelbasierte Sprache, der eine Eingabe erhält, diese interpretiert und das Ergebnis als Array von Zahlen ausgibt. Es sollte jedes Byte durchlaufen und eine andere Funktion basierend auf dieser Tabelle ausführen:
0000 (0): Verketten (Kombinieren Sie die beiden oberen Zahlen eines Stapels wie eine Zeichenfolge. Beispiel: 12,5 -> 125)
0001 (1): Inkrementieren Sie (Addieren Sie 1 zu der Zahl oben auf dem Stapel)
0010 (2): Dekrement (subtrahieren Sie eins von der Zahl oben auf dem Stapel)
0011 (3): Multiplizieren (multiplizieren Sie die beiden oberen Zahlen im Stapel)
0100 (4): Dividieren (dividieren Sie die Zahl von 2 nach oben durch die oberste Zahl auf dem Stapel)
0101 (5): Addieren (Addiere die beiden obersten Zahlen auf dem Stapel)
0110 (6): Subtrahieren (Subtrahiere die oberste Zahl auf dem Stapel von der darunter liegenden Zahl)
0111 (7): Exponent ( Berechnen Sie die zweithöchste Zahl nach der höchsten Zahl.
1000 (8): Modul: (Finden Sie die zweithöchste Zahl, modulo die höchste Zahl.)
1001 (9): Drehe nach rechts (Verschieben Sie den Stapel um eins nach unten. Die Zahl unten befindet sich jetzt oben.)
1010 (A): Nach links drehen (Verschieben Sie den Stapel um eins nach oben. Die Zahl oben befindet sich jetzt unten.)
1011 (B): Duplizieren (Kopieren Sie die oberste Zahl so, dass sie zweimal erscheint. Beispiel: 4,1 wird zu 4,1,1.)
1100 (C): Doppeltes Duplizieren (Kopieren Sie die obersten beiden Zahlen auf dem Stapel. Beispiel: 4, 1,2 wird zu 4,1,2,1,2)
1101 (D): Swap (Vertausche die beiden oberen Zahlen auf dem Stapel. Beispiel: 4,1,2 wird zu 4,2,1)
1110 (E): Double Swap (Vertausche die oberen beiden Zahlen mit zwei darunter. Beispiel: 1,2,3,4,5 wird 1,4,5,2,3)
1111 (F): Delete / Pop (Entferne die Zahl oben auf der Stapel)
Zum Beispiel eine Datei mit
1 1 BC 5 C 5 B 9 5 - Eingang (hex) | | | | | | | | | | 1 2 2 2 4 4 6 6 2 8 - Stapel 2 2 2 2 4 6 6 6 2 2 4 2 4 6 4 2 2 2 2 4 2 2 2 2
würde ausgeben [8,6,4,2]
Regeln:
- Unicode / Symbole sind in Ordnung, aber ASCII ist am besten.
- Seien Sie kreativ! Kürze zählt, aber Kreativität ist großartig!
- Wenn die Bytes zu hart sind, verwenden Sie
"$iv*/+-^%><dtsz."
oder"0123456789ABCDEF"
anstelle der tatsächlichen Bytes. - GESCHWINDIGKEIT! Je schneller desto besser.
- Die Punktzahl basiert auf dem Ruf, aber die Größe ist ein großer Faktor.
Bonus:
Versuchen Sie, diese Herausforderung mit Ihrem neu erstellten Interpreter so kurz wie möglich zu beenden .
Hinweis:
Das Besondere an dieser Herausforderung im Gegensatz zu anderen Code-Golf-Herausforderungen ist, dass es keinen Code dafür gibt. Wenn Sie beispielsweise einen Brainf * ck-Interpreter schreiben müssten, könnten Sie sich die Implementierungen anderer Leute ansehen. Mit diesem kannst du das nicht machen.
Ich habe vergessen, das Enddatum anzugeben. Ich schätze, ich werde es einen Monat nach dem Erschaffen schaffen. Person mit den höchsten Stimmen am 22. Februar gewinnt!
quelle
Antworten:
Ruby, 67 Zeilen Regex-Substitutionen
Ich beschloss, den Interpreter in Regex zu schreiben und mich dabei an effiziente Algorithmen zu halten.
Ich hätte für einfache Bytes gehen können, aber die Verwendung von Symbolen macht den Code meiner Meinung nach besser lesbar. Natürlich, wenn wir zwei Anweisungen in ein Byte packen könnten ...
Die Verkettung negativer Werte führt zu einem Komplementverhalten der Zehn, das die interne Darstellung widerspiegelt.
Division ist eine Ganzzahldivision und der Rest ist niemals negativ.
Was die Bonusrunde betrifft, ist die kürzeste Lösung, die ich mir ausgedacht habe ( 13 Zeichen ), eine saubere Lösung:
quelle
d
(nachdemii
der Stapel nur2
nichts zum Tauschen enthält ) und das Endbuchstaben rotiert (zumindest das erste, das zweite ist nur ein Tausch in Verkleidung ...). ) sollte links sein, nicht rechts.x86-Assembly (unter Win32)
"SPEED!" Scheint hier enorm wichtig zu sein, und wir alle wissen, dass Assemblersprache in dieser Hinsicht nichts besser ist als Assemblersprache. Also machen wir das in der Montage!
Dies ist eine Implementierung der Sprache in der x86-Assemblersprache (in NASM-Syntax), wobei die Zahlen als vorzeichenlose 32-Bit-Ganzzahlen gespeichert und interpretiert werden, wobei der native x86-Stapel direkt verwendet wird. Ein Stapelunterlauf und -überlauf während einer arithmetischen Operation (oder Division durch Null) ist ein Laufzeitfehler, der das Programm mit einer Fehlermeldung beendet.
Verwenden Sie zum Kompilieren so etwas wie
Das Programm empfängt den Namen der Binärdatei, die das Programm enthält, in der Befehlszeile (z. B.
nexlang.exe testprg.bin
. ). Anschließend wird der endgültige Inhalt des Stapels in einem für Menschen lesbaren Format auf die Standardausgabe gedruckt.Speichern Sie zum Testen Folgendes in
nex.def
:Und dann schreiben Sie Ihre NEX-Programme ("nicht existent", wie im Fragentitel genannt) unter Verwendung der oben definierten Mnemonik und kompilieren sie mit so etwas wie
Verwenden Sie für den ursprünglichen Testfall beispielsweise Folgendes
prg.nex
:Verwenden Sie schließlich für die Herausforderung „2014“ das folgende 14-Byte-NEX-Programm:
quelle
LEA ESI, [ESI+1]
lieber alsINC ESI
?GolfScript, 64 Zeichen
OK, also habe ich beschlossen, dies zu versuchen und Golf zu spielen. Und welche bessere Sprache zum Golfen als GolfScript?
Praktischerweise ist GolfScript selbst bereits eine stapelbasierte Sprache mit Einzelbyte-Befehlen, und 11 von 16 Befehlen werden direkt den integrierten GolfScript-Befehlen zugeordnet. Alles, was ich wirklich tun muss, um Ihre Sprache zu interpretieren, ist die restlichen fünf Befehle in GolfScript zu implementieren und eine Übersetzungstabelle zu erstellen:
Der Code wirkt etwas verteilt, weil ich Zeilenumbrüche als Begrenzer für die Übersetzungstabelle verwende. Die Initiale
0\
drückt eine Null auf den Stapel und verschiebt ihn unter das Eingabeprogramm. Die{ }/
Schleife, die den größten Teil des Codes enthält, nimmt das Eingabeprogramm vom Stapel und iteriert den Schleifenkörper über jedes seiner Zeichen und das Finale]-1%`
sammelt den Stapel in einem Array und kehrt ihn um (da die Beispielausgabe am oberen Rand des Stapels beginnt) Stack) und stringifiziert es.Der Schleifenkörper beginnt mit einer 16-zeiligen Zeichenfolge in Anführungszeichen.
n%
Teilt diese Zeichenfolge an Zeilenumbrüchen auf,=
sucht die dem Eingabezeichen entsprechende~
Teilzeichenfolge und wertet sie als GolfScript-Code aus.Hier sind die GolfScript-Implementierungen der 16 Befehle:
`+~
: zwei Zahlen als Zeichenketten verketten)
: Inkrement(
: Dekrement*
: multiplizieren/
: teilen+
: add-
: subtrahieren?
: zur Macht erheben%
: Modul](+~
: Stapel nach rechts drehen])\~
: Stapel nach links drehen.
: Duplikat1$1$
: doppeltes Duplikat\
: Swap[@]\+~\
: doppelter Swap;
: PopMit dem doppelten Tausch bin ich ein bisschen unzufrieden - er ist hässlich und viel länger als alle anderen Befehle. Es fühlt sich an, als gäbe es einen besseren Weg, aber wenn ja, habe ich ihn noch nicht gefunden. Immerhin funktioniert es.
Führen Sie zum Beispiel das obige Programm für die Eingabe aus (angegeben als doppelte Anführungszeichenfolge für GolfScript / Ruby / Perl / Python / usw.):
ergibt die Ausgabe:
Bearbeiten: Es ist mir gelungen, zwei weitere Zeichen für insgesamt 62 Zeichen mit einer kompakteren Codierung der Übersetzungstabelle zu speichern . Dies beeinträchtigt jedoch die Lesbarkeit:
Zu den bemerkenswerten Merkmalen dieser Version gehört der
(
am Anfang der Schleife stehende Index, der die Befehlsindizes von 0..15 auf -1..14 verschiebt, sodass ich die lange Folge von Einzelzeichenbefehlen von 1 auf 8 am Anfang setzen kann des Tisches. Auf diese Weise kann ich sie in einer separaten Zeichenfolge speichern und die acht sie begrenzenden Zeilenumbrüche entfernen. Leider kostet mich die zusätzliche Komplexität an anderer Stelle sechs Zeichen.quelle
+
in])\+~
Haskell
Aus Spaß habe ich eine Lösung entwickelt, die keinerlei Variablen verwendet, sondern nur Funktionen miteinander kombiniert.
quelle
Rubin,
330316 ZeichenIch beschloss, Golf zu spielen. (Weil das immer Spaß macht.)
Der Hauptteil ist dieser:
Es übersetzt jede hexadezimale Ziffer in eine Ganzzahl zur Basis 10 und verwendet dann die
[(huge array of strings)]
, um die richtige Zeichenfolge zu finden, die diesen Befehl darstellt. Dann ist eseval
diese Saite.Beachten Sie, dass dies
%w[x y z]
äquivalent zu ist['x','y','z']
.Mir gefällt auch, wie man in dieser Zeile Smileys findet! Einige von ihnen sind
:*
:/
:-]
:%
Probelauf:
quelle
C -
642634 Zeichen$iv*/+-^%><dtsz.
Nur für den Dialekt (q
wird zusammen mit als Endzeichen hinzugefügt0
):Lösung für die 2014 Herausforderung:
dididiizs>
.quelle
free(a);
. Und sollte es nicht<<2
in denrealloc
Anrufen sein?free()
Erinnerung gewöhnt: Pk, 228
Die Implementierung ähnlicher Anweisungen wiederholt sich ziemlich oft, was wahrscheinlich zu einem gewissen Grad entfernt werden kann.
quelle
C
924882622603587569562 ZeichenMit offensichtlichen Zeilenumbrüchen entfernt (zur besseren Lesbarkeit beibehalten).
Dies implementiert die Interpretation "underflow pushed zero" aus Jan Dvoraks Kommentar.
Die Golfversion hat sich unter dem (willkommenen) Druck der guten Antwort von Oberon im Vergleich zur ungolfed Version hier tatsächlich wesentlich verändert .
Ich stellte fest, dass ich durch das Ersetzen der
switch
Aussage zugunsten einerif
...else
-Kette alle Ziffern aus meinen Fällen herausrechnen konnte . Stattdessen wird diew
Variable mit 47 initialisiert , sodass sie mit einem Inkrement auf 48 (== ascii'0'
) erhöht wird. Anschließend wird jede Inkrementierungw
so lange fortgesetzt, bis'A'
das meist leere erste Makroargument verwendet wird, das eine zusätzliche 7 hinzufügt, um aufzustehen zu einer'. Die ungolfed Version ist mein Lieblings - Showsbrk
/SIGSEGV
Tricks „frei“ Speicher ohne weitere Zuweisungen zu erhalten.quelle
log
ist nicht einmal definiert.R, 428 Zeichen
Mit Einrückungen:
In Aktion:
quelle
JavaScript, 685
Nicht Golf Version ( Kern ):
Golf Version:
Beispiel:
quelle
Haskell
Laufen
quelle
tr
?), Ist dies möglich.Common Lisp - 589
Akzeptiert hexadezimale Eingaben ohne Leerzeichen.
Ungolfed:
quelle
PHP
es ist nicht das schönste, aber es funktioniert.
Läuft von der Shell aus und erwartet einen Dateinamen als erstes Argument. es akzeptiert einen der 3 Dialekte (auch gemischt)
Verhalten nicht für negative oder fehlende Index definiert
quelle
PureBasic -
2821891 ZeichenDies ist ein interaktiver Interpreter - keine Datei, Sie geben nur die Codes 0-9, AF ein, und er führt diesen Befehl aus und zeigt ihn als Beispielbeitrag an.
Verwenden Sie "X" oder "Q", um den Vorgang zu beenden.
Das hat wirklich Spaß gemacht :)
Bearbeiten: Nach dem Schlafengehen dachte ich, ich würde Golf spielen - ich habe die lesbare Version jedoch zum Nachschlagen gelassen.
Alles funktioniert genauso, außer dass ich das Q oder X zum Beenden entfernt habe. Schließe einfach das Fenster, um es zu beenden:
quelle
Common Lisp - 586
Ungolfed
Bindet einen neuen Stapel im makroexpandierten Code lexikalisch: kein Verweis auf eine globale Variable. Außerdem wird es bis auf den Maschinencode kompiliert.
Beispiel
quelle
Python 2, 508 Bytes
Verwendet die Codierung "0123456789ABCDEF". Ich bin wirklich stolz darauf, wie sich dieser herausgestellt hat. Es liest keine Datei, es wird von STDIN eingegeben, aber wenn das ein Problem ist, kann es leicht geändert werden.
2 Lösungen für das Problem 2014:
B11CB3A1AED0A00
(16 -15 Byte) - Allgemeiner Verkettungssatz.BB102CD11B513B3622E
(20 bis19 Byte) - Viel kühler - Wertet zu (5 * (10-1)) ^ 2-11 ausquelle
Python 2, 955 Bytes
Was jede Funktion macht
quelle