Ziel dieser Herausforderung ist es, (eventuell) jedes mögliche Stopp-Programm in einer Sprache Ihrer Wahl auszugeben . Das mag zunächst unmöglich klingen, aber Sie können dies mit einer sehr sorgfältigen Auswahl der Ausführungsreihenfolge erreichen.
Unten sehen Sie ein ASCII-Diagramm, um dies zu veranschaulichen. Lassen Sie die Spalten eine Nummerierung jedes möglichen Programms darstellen (jedes Programm ist eine endliche Anzahl von Symbolen aus einem endlichen Alphabet). Es sei jede Zeile ein einzelner Schritt bei der Ausführung dieses Programms. Eine X
Darstellung der Ausführung, die von diesem Programm zu diesem Zeitpunkt ausgeführt wurde.
step# p1 p2 p3 p4 p5 p6
1 X X X X X X
2 X X X X X
3 X X X X
4 X X X X
5 X X X
6 X X
7 X X
8 X X
9 X X
∞ X X
Wie Sie sehen, halten die Programme 2 und 4 nicht an. Wenn Sie sie einzeln ausführen, bleibt Ihr Controller in der Endlosschleife von Programm 2 stecken und gibt niemals Programme ab 3 aus.
Stattdessen verwenden Sie einen Verzahnungsansatz . Die Buchstaben stellen eine mögliche Ausführungsreihenfolge für die ersten 26 Schritte dar. Die *
s sind Stellen, an denen das Programm angehalten und ausgegeben wurde. Die .
s sind Schritte, die noch nicht ausgeführt wurden.
step# p1 p2 p3 p4 p5 p6
1 A C F J N R V
2 B E I M Q * Z
3 D H * P U
4 G L T Y
5 K O X
6 * S .
7 W .
8 . .
9 . .
∞ . .
Anforderungen an die Zielsprache
Die Zielsprache (die parallel gedolmetscht wird) muss Turing-vollständig sein. Ansonsten kann es sich um jede Sprache handeln, die Turing-vollständig ist, einschließlich Turing-vollständiger Untergruppen von viel größeren Sprachen. Sie können auch zyklische Tag-Systemregeln interpretieren. Sie können auch eine zu testende Sprache erstellen, sofern Sie nachweisen können, warum Turing vollständig ist.
Wenn Sie beispielsweise Brainfuck testen möchten, ist es am besten, nur die []-+<>
Teilmenge zu testen , da die Eingabe nicht unterstützt wird und die Ausgabe einfach weggeworfen wird (siehe unten).
Wenn es um das "Controller" -Programm (auf dem Sie Golf spielen) geht, gibt es keine besonderen Anforderungen. Es gelten die normalen Sprachbeschränkungen.
So erstellen Sie eine unendliche Liste von Programmen
Die Mehrheit der Programmiersprachen kann als eine Reihe von Symbolen aus einem endlichen Alphabet dargestellt werden. In diesem Fall ist es relativ einfach, eine Liste aller möglichen Programme in aufsteigender Reihenfolge aufzulisten. Das von Ihnen verwendete Alphabet sollte für die Anforderungen der Zielsprache repräsentativ sein . In den meisten Fällen ist dies druckbares ASCII. Wenn Ihre Sprache zusätzlich Unicode unterstützt, sollten Sie nicht jede mögliche Kombination von Unicode-Zeichen testen, sondern nur ASCII. Wenn Ihre Sprache nur verwendet []-+<>
, testen Sie die verschiedenen Kombinationen von "Kommentar" -ASCII-Zeichen nicht. Sprachen wie APL hätten ihre eigenen speziellen Alphabete.
Wenn Ihre Sprache nicht alphabetisch beschrieben werden kann, wie z. B. Fractran oder Turing Machines, gibt es andere gleichermaßen gültige Methoden, um eine Liste aller möglichen gültigen Programme zu erstellen.
Interpretation einer ständig wachsenden Liste von Programmen
Der Schlüssel zu dieser Herausforderung besteht darin, einen parallelen Interpreter für eine wachsende Liste von Programmen zu schreiben. Hierfür gibt es einige grundlegende Schritte:
- Fügen Sie der Liste eine endliche Anzahl von Programmen hinzu
- Interpretieren Sie jedes Programm auf der Liste für einen begrenzten Zeitraum einzeln. Dies kann erreicht werden, indem für jeden Befehl ein Schritt ausgeführt wird. Speichern Sie alle Zustände.
- Entfernen Sie alle terminierenden / fehlerauslösenden Programme aus der Liste
- Die sauber gestoppten * Programme ausgeben
- Fügen Sie der Liste weitere Programme hinzu
- Simulieren Sie nacheinander jedes Programm und nehmen Sie die Ausführung älterer Programme dort auf, wo sie aufgehört haben
- Entfernen Sie alle terminierenden / fehlerauslösenden Programme aus der Liste
- Die sauber gestoppten * Programme ausgeben
- wiederholen
* Sie sollten nur Programme ausgeben, die sauber anhalten. Dies bedeutet, dass während der Ausführung keine Syntaxfehler oder nicht erfassten Ausnahmen aufgetreten sind. Programme, die zur Eingabe auffordern, sollten ebenfalls beendet werden, ohne sie auszugeben. Wenn ein Programm eine Ausgabe erzeugt, sollten Sie es nicht beenden, sondern einfach die Ausgabe wegwerfen.
Weitere Regeln
- Sie dürfen keine neuen Threads erzeugen, um die getesteten Programme zu enthalten, da dies die Parallelisierungsarbeit auf das Host-Betriebssystem / andere Software verlagert.
- Bearbeiten: Um potenzielle zukünftige Lücken zu schließen, dürfen Sie keinen
eval
Teil des Codes des getesteten Programms (oder einer verwandten Funktion) . Sie könneneval
einen Codeblock aus dem Interpretercode erstellen. (Die BF-in-Python-Antwort ist nach diesen Regeln weiterhin gültig.) - Das ist Code-Golf
- Die Sprache, in der Sie Ihren Beitrag verfassen, muss nicht mit der Sprache übereinstimmen, die Sie testen / ausgeben.
- Sie sollten davon ausgehen, dass Ihr verfügbarer Speicher unbegrenzt ist.
- Wenn Sie die Turing-Vollständigkeit nachweisen, können Sie davon ausgehen, dass die Eingabe fest im Programm codiert ist und die Ausgabe aus dem internen Status des Programms gelesen werden kann.
- Wenn Ihr Programm sich selbst ausgibt, ist es wahrscheinlich falsch oder polyglott.
"If your program outputs itself, it is probably wrong or a polyglot."