In dieser Herausforderung schreiben Sie einen Interpreter für 2 Ω (transkribiert als TwoMega ), eine Sprache, die lose auf Brainfuck mit einem unendlich dimensionalen Speicherplatz basiert .
Die Sprache
2 Ω enthält drei Zustandselemente:
Das Band , eine unendliche Liste von Bits, wurde alle auf 0 initialisiert. Es hat ein Element ganz links, aber kein Element ganz rechts.
Der Speicherzeiger , eine nicht negative Ganzzahl, die ein Index eines Elements im Band ist. Ein höherer Speicherzeiger bezieht sich auf eine Bandzelle weiter rechts; Ein Speicherzeiger von 0 bezieht sich auf das Element ganz links. Der Speicherzeiger wird auf 0 initialisiert.
Der Hypercube , eine konzeptionell ∞- dimensionale "Box" von Zellen, von denen jede ein auf 0 initialisiertes Bit enthält. Die Breite des Hypercubes ist in jeder Dimension an nur 2 Zellen gebunden, aber die Unendlichkeit der Dimensionen bedeutet die Anzahl von Zellen ist unzählig .
Ein Index in den Hypercube ist eine unendliche Liste von Bits, die sich auf eine Zelle im Hypercube bezieht (genauso wie eine endliche Liste von Bits verwendet werden könnte, um auf einen Hypercube mit endlicher Dimension zu verweisen). Da das Band eine unendliche Liste von Bits ist, bezieht sich das gesamte Band immer auf ein Element des Hypercube. Dieses Element wird als Referent bezeichnet .
2 Ω gibt 7 verschiedenen Zeichen Bedeutung:
<
Dekrementiert den Speicherzeiger um 1. Das Dekrementieren unter 0 ist ein undefiniertes Verhalten, sodass Sie nicht damit umgehen müssen.>
erhöht den Speicherzeiger um 1.!
dreht das Bit beim Referenten um..
gibt das Bit am Referenten aus.^
Ersetzt das Bit an der Zelle, auf die der Speicherzeiger auf dem Band zeigt, durch die Umkehrung des Bits am Referenten.[x]
führt den Codex
aus, solange das Bit am Referenten 1 ist.
Die Herausforderung
Ihre Aufgabe ist es, ein Programm zu schreiben, das eine Zeichenfolge als Eingabe verwendet und diese Eingabe als 2 Ω- Programm ausführt .
Dies ist Code-Golf , daher gewinnt die kürzeste gültige Antwort (gemessen in Bytes).
Anmerkungen
- Sie können davon ausgehen, dass das Programm nur aus den Zeichen besteht
<>!.^[]
und[]
ordnungsgemäß verschachtelt ist. - Ihr Interpreter sollte nur durch den verfügbaren Speicher im System begrenzt sein. Es sollte in der Lage sein, die Beispielprogramme in angemessener Zeit auszuführen.
Beispielprogramme
Druck 1:
!.
Drucken 010:
.!.!.
0 für immer drucken:
![!.!]
Drucken Sie 0 für immer oder 1 für immer, wenn !
vorangestellt wird:
[.]![!.!]
quelle
1
s auf dem Band immer begrenzt ist. Tatsächlich gibt es eine ziemlich einfache Bijektion zwischen den natürlichen Zahlen und den Bandzuständen (interpretieren Sie den Bandinhalt als rückwärts gerichtete Binärzahl), was zeigt, dass der Hypercube im Grunde ein unendliches 1D-Array ist, auf das durch Umdrehen von Bits in einem ganzzahligen Zeigerwert zugegriffen wird , anstatt wie beim Brainfuck in / dekrementieren.cat
Programm zu schreiben : Es scheint keine Anweisung für die Eingabe zu geben..
- druckt eine einzelne Null und existiert dann;!^!.
- druckt einen einzelnen und wird dann beendet. Mehr wäre aber gut. Im Moment muss man die Einsendungen verstehen, um sie zu verifizieren (und sie daher zu verbessern!)[0,0,0,0,0,0,0...]
(dh das Vorhandensein von a!
zu Beginn des Programms).[.]![!.!]
, um den Wert dieser Zelle für immer zu druckenAntworten:
Python 2 , 167 Bytes
Probieren Sie es online aus!
t ist das Band. t = 6 bedeutet, dass das Band [0 1 1 0 0 0…] ist.
m ist 2 hoch zur Potenz des Speicherzeigers. So m = 8 Mittel auf Band wir zeigen Bit 3.
h ist der Hyperwürfel. h = 80 (Bits 4 und 6 gesetzt) bedeutet, dass die Bits bei [0 0 1 0…] und [0 1 1 0…] gesetzt sind.
Um das Bit beim Referenten zu lesen, überprüfen wir 2 t & h . Um es umzudrehen, führen wir h ^ = 2 t aus .
Wir übersetzen die Anweisungen in Python-Code und führen das Ergebnis aus. Ich speichere die Einrückungsstufe der while-Schleifen.
quelle
2**t
(-6 Bytes).JavaScript (Node.js) , 148 Byte
Probieren Sie es online aus!
Es ist komplett
Benötigen Sie init, um sich an einigen Stellen nach rechts zu bewegen, und initiieren Sie das aktuelle und rechte Bit der Adresse als 1 (
>>>>>>>>^>^<
)Probieren Sie es online aus!
Platz
n
in BoolFuck ist geschrieben als(0, 0, ..., 0(n*0), [1], 1, 0, 0, ...)
.Denn
>
es tutn
=>n+1
Gleich wie
<
funktioniertquelle
!>.
Drucke1
in boolfuck aber übersetzen!>^.
die 1 in TwoMega druckt (>
das Band nicht beeinträchtigt,^
haben keinen Einfluss auf das Band , da der referenten 1)+>;
do[1]00...
1[0]0...
(Ausgabe 0),!>^.
do(0,0,...)=1, ptr=([0],0,...)
(0,0,...)=1, ptr=(0,[0],...)
(0,0,...)=1, ptr=(0,[1],...)
(Ausgabe 0), was ist los?!>.
, nur>
ist ein gültiger Befehl in Boolfuck ...!
der Referent invertiert, nicht die Bandzelle .Brain-Flak Classic , 816 Bytes
Probieren Sie es online aus!
Dieser Code wurde nur geschrieben, damit ich einen Beweis für die Vollständigkeit von Turing schreiben kann.
Nachweis der Turing-Vollständigkeit
Wir zeigen eine Reduzierung von Boolfuck auf TwoMega:
Diese Übersetzung speichert den Boolfuck-Status in den geradzahligen Bandzellen in TwoMega. Alle übersetzten Befehle behalten die folgenden Invarianten bei:
Das Snippet
!^!
bleibt[0]0
konstant und wechselt zwischen0[0]
und[1]1
(wobei die Aufmerksamkeit auf die Linie auf dem Hypercube beschränkt ist, die erreichbar ist, ohne den Speicherzeiger zu bewegen). Als solches wird es verwendet, um den aktuellen Bandwert vorübergehend in den Referenten für die Boolfuck-Befehle zu setzen, die sich darum kümmern.Wenn TwoMega einen Eingabebefehl
,
mit der erwarteten Semantik erhalten würde, würde der Boolfuck-Befehl,
in übersetzt>^<,!^>[!]!^<
. Da,
es nicht erforderlich ist, zu beweisen, dass Boolfuck Turing-vollständig ist, hat das Fehlen eines Eingabebefehls keinen Einfluss auf diesen Beweis.quelle
Python 3 ,
297284274 Bytes-10 Bytes dank Ovs und Jonathan Allan
Probieren Sie es online aus!
quelle
t.discard(p)
->t-={p}
t
istglobal
.f
alsf(C,p,t=set())
Pip ,
7571 BytesProbieren Sie es online aus!
Übersetzt den 2 Ω- Code in einen äquivalenten Pip-Code und wertet ihn aus.
Wir verwenden
i
das Band,v
den Bandzeiger * undl
den Hypercube. Die ersten beiden sind auf nützliche Werte vorinitialisiert;l
beginnt als[]
, auf die wir ein0
(lPU0
) drücken , um Probleme beim Indizieren von leeren Listen zu vermeiden.* Eigentlich ist es die bitweise Negation des Bandzeigers, da wir das Band rückwärts speichern, um die Konvertierung in Dezimalzahlen zu vereinfachen.
Der Rest des Codes lautet:
Die Übersetzungstabelle:
l@FBi
ist das referent: Element des Hypercubel
am Index (i
von binär konvertieren ). Es erscheint oft, also nennen wir es_
und ersetzen es_
am Ende durch den echten Code.!:_
negiert logisch den vorhandenen Referenten.--viPU0
Dekrementev
(Bewegen des Bandzeigers nach rechts); Anschließend wird ein weiterer0
nach links gedrückti
, um sicherzustellen, dass der Bandzeiger in Grenzen bleibt.++v
Inkrementev
(keine Notwendigkeit zur Überprüfung der Grenzen pro OP).W_{
führt eine Schleife aus, während der Referent wahr ist (dh ungleich Null, dh1
).}
schließt die Schleife.O_
gibt den Referenten ohne Zeilenumbruch aus.Zum Schluss für
^
:quelle