Nicht schlecht für eine ziemlich wortreiche Turing-Plane ...
N
Count i while _%128-9 {
Count x while _/128%2 {
Write 40
_+128
}
Write _%128
_+128-_%128+N
}
Count j while _/256-j {
Write 41
}
(Ja, das ganze Leerzeichen ist obligatorisch.)
Hinweis: Wegen der Eingabebeschränkungen von Acc !! Ist es nicht möglich, eine beliebige Zeichenfolge ohne Endbegrenzer zu lesen? Daher erwartet dieses Programm die Eingabe (in stdin) als Zeichenfolge, gefolgt von einem Tabulatorzeichen.
Acc !! ?
Es ist eine Sprache, die ich erstellt habe und die nur unbrauchbar zu sein scheint . Der einzige Datentyp ist Integer, das einzige Kontrollflusskonstrukt ist die Count x while y
Schleife und die einzige Möglichkeit, Daten zu speichern, ist ein einzelner Akkumulator _
. Die Ein- und Ausgabe erfolgt zeichenweise unter Verwendung des speziellen Werts N
und der Write
Anweisung. Trotz dieser Einschränkungen bin ich mir ziemlich sicher, dass Acc !! ist Turing-komplett.
Erläuterung
Die Grundstrategie in Acc !! Bei der Programmierung wird der Akkumulator konzeptionell durch Mod- %
und Integer-Division /
partitioniert, sodass mehrere Werte gleichzeitig gespeichert werden können. In diesem Programm werden drei solcher Abschnitte verwendet: Die sieben Bits ( _%128
) niedrigster Ordnung speichern einen ASCII-Code von der Eingabe; das nächste Bit ( _/128%2
) speichert einen Flag-Wert; und die verbleibenden Bits ( _/256
) zählen die Anzahl der von uns benötigten engen Parens.
Eingabe in Acc !! kommt von dem speziellen Wert N
, der ein einzelnes Zeichen liest und zu seinem ASCII-Code auswertet. Jede Anweisung, die nur aus einem Ausdruck besteht, weist das Ergebnis dieses Ausdrucks dem Akkumulator zu. Also speichern wir zunächst den Code des ersten Zeichens im Akkumulator.
_%128
speichert das zuletzt gelesene Zeichen. Die erste Schleife läuft also solange _%128-9
, bis das aktuelle Zeichen ein Tabulator ist.
Innerhalb der Schleife möchten wir drucken, es (
sei denn, wir befinden uns in der ersten Iteration. Seit Acc !! Wenn keine if-Anweisung vorhanden ist, müssen Schleifen für Bedingungen verwendet werden. Wir verwenden das 128-Bit des Akkumulators _/128%2
als Flag-Wert. Beim ersten Durchlauf ist das einzige, was sich im Akkumulator befindet, ein ASCII-Wert <128, daher ist das Flag 0 und die Schleife wird übersprungen. Bei jedem weiteren Durchgang stellen wir sicher, dass das Flag 1 ist.
Innerhalb der Count x
Schleife (wenn das Flag 1 ist) schreiben wir einen offenen Paren (ASCII 40
) und addieren 128 zum Akkumulator. Dadurch setzen wir das Flag auf 0 und verlassen die Schleife. Dies geschieht auch, um den Wert von _/256
zu erhöhen, den wir als unsere Liste der auszugebenden engen Parens verwenden werden.
Unabhängig vom Wert des Flags schreiben wir das neueste Eingabezeichen, was einfach ist _%128
.
Die nächste Anweisung ( _+128-_%128+N
) führt zwei Dinge aus. Durch Hinzufügen von 128 wird zunächst das Flag für den nächsten Durchlauf der Schleife gesetzt. Zweitens wird der _%128
Slot auf Null gesetzt, ein anderes Zeichen gelesen und dort gespeichert. Dann schleifen wir.
Wenn die Count i
Schleife beendet wird, haben wir gerade ein Tabulatorzeichen gelesen und der Akkumulatorwert bricht folgendermaßen zusammen:
_%128
: 9
(das Tabulatorzeichen)
_/128%2
: 1
(die Flagge)
_/256
: Anzahl der gelesenen Zeichen minus 1
(Das Minus 1 liegt daran, dass wir beim ersten Durchlauf durch die Hauptschleife nur einmal 128 zum Akku addieren.) Alles, was wir jetzt brauchen, sind die engen Parens. Count j while _/256-j
Schleifen Sie die _/256
Zeiten ab und schreiben Sie 41
jedes Mal ein enges Paren (ASCII ). Voila!