Brainfuck , 6013 4877 4376 Bytes
Edit: -1136 Bytes. Es wurde auf eine bessere Methode zum Generieren der Daten für die Quine umgestellt
Edit2: -501 Bytes. Ich habe meinen Selbstinterpretierer erneut besucht und ein paar Hundert Bytes reduziert
->++>++++>+>++>+++>>++++>>++++>>+++>>++++>>+++>>++>++>++>++>++>++>++>++>++>++>++++>+++++>+>++>++>++>++>++>++>>+++>+>++>++>++++>+>+++>+>++++>+>+++>+>++>>>+++++>++++>++++>>+++>>++++>>+++>>++>++>++>++>++>++>++>++++>+++++>+>++>++>++>++>++>++>>+++>+>++>++++>+>+++>+>++++>+>+++>+>++>>>+++++>+++>>+++>+>+++++>+++++>++++>>++>+>++>++>++>++>++>++>+++>>++>++>>++++>>+++>++>++>++>++>++>++++>+++++>>++>++>++>+>+++>>++++>>++>++>++>>++>++>++>>++>++>++>>++>++>++>++>++>++>>++>++>++>++>++>++>>++>++>++>>++>++>++>++>>++>++>++>++>++++>+>+++>>+++++>+++>>++>>+++++>>>++>>++>++>++>>+++++>+++++>>>++>++>++++>+>+++>+>+>++++>+>+++>+>+>++++>+>+++>>++++>++++>++++>>+++>>>++++>>+++>>>++++>>+++>+>++++>+++++>>>++>+>+>+++>+>++++>+>+++>+>+>++++>+>+++>+>+>++++>+>+++>>+++++>+++>>++++>>+++>>>++++>>+++>>>++++>>+++>>>++++>+++++>+>+>++>++++>+>+++>+>++>>>++++>>+++>>+++>+>+>++++>++++>+++++>>++>+>+++>+>+++>>>++++>>+++>>++++>++++>+++++>+>++>>+++>>+++>+>+>++++>+>+++>+>+>++++>+>+++>+>+>++++>+>+++>>+++>>>>++++>>+++>>>++++>>+++>+>++++>++++>+++++>+++>+>+++>>>>++++++>++++>>++>++>++>++>++>++>++>++++>+>+++++>+++++>+++++>+++++>+++++>+++++>>+++++>+++>++>+>+++++>++++>>+++>>++++>+>++>+>++>>>>>+++>+>+>+>+++++>++++>>+++>>++++>+>++>+>++>>>>>+++>+>+>+>+++++>++++>>+++>>++++>+>++>+>++>>>>>+++>+>+>+>+++++>++++>>+++>>++++>+>+++++>+>++>++>++>>>>>+++>+>+>+>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>++++>>+++>>++++>+>++>++>+>++>>>>>+++>+>+>+>+++++>+++++>++++>>+++>>++++>+>+++++>+>++>++>++>++>++>++>++>>>>>+++>+>+>++>++>++>++>++++>+++++>+>+++++>+++++>+++++>+++++>+++++>+++++>>+++>++>+>++>++++>>+++>>++++>+>++>++>+>++>>>>>+++>+>+>+>+++++>+++++>++++>>+++>>++++>+>+++++>+>++>>>>>+++>+>+>+++++>+>++++>++>+++>+>++++>>+++>>++++++>+++>>>>++>+>+>+>+>+++++>++++>+>+++>>++++>+++++>++++>+>+>+++>>++++>+>++>++++>>+++>>>++++>+>+++>+>+>++++>>>++>++++>+>+>++++>+>+++>+>+>+++++>++++>>>+++>+>++++>>>>>++++>>+++>>++>+>+>++++>+>+++>+>+++>+>+++++>++++>>>+++>+>++++>>>>>++++>>+++>>+++++>+>+>++++>+>+++>+>+++>+>++>++>++++>+++++>>>++>+>+>+++>>>++++>>+++>>+++>+>+++>+>++++>+>+++>>+++++>+>+++>>+++++>++++>+>+>+++>>++++>+>++>++>++++>>+++>>>++++>+>+>+++>>++++>+>+>++>++++>+>+>++++>+>+++>>++++>+++++>+>+>++>>>+++>>+++++>+++++>++++>+>+>+++>>++++>++++>>+++>>++>+>+>++++>+>+++>+>+++>>++>++++>+>+>+++>>++++>++++>>+++>>+++++>+>+>++++>+>+++>+>+++>>++>++++>>+++>>+++>+++>+>+>++++>+>+++>>+++++>+++++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>+++++++>+>+>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>+++++>+>+>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>++++++>+>+>+>++++>+>+++>+>+>+>++++>+>+++>+>++++>+>+++>>++++>++++>>+++>>++++>>+++>>>>++++>>+++>>>++>+>+>+>++++>+>+++>+>+>+>++++>+>+++>+>++++>+>+++>>+++++>+++>>++++>>+++>>++++>>+++>>>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>++>+>+>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>>++++>>>+++>>++++>+>+>+>++++>+>+>+++>+>++>>>>++++>>>+++>>+++++>+++>>++++>+++++>+++>+>+>++>++++>+>++++>+++++>>>++>+>+>+++>+>+++>+>++++>+++++>>>++>+>+>+++>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>++>++>++++>+++++>+++++>>++++>+++++>+>+>++>>>+++>>+++>++>+>+>+++++>++++>++>++>+>+>+++>+>++++>+++++>>>>++++>>>+++>>++>+>+>+>++++>+>+>+++>+>+++>+>++++>+>+++>+>+++>+>++>++>++>++>++>++>++>++>>>++++>++>+>+>+++++>>>+++>>+++>>>++++>++++[<+]>[>[>]>[>]>++++++++++[-<++++++>]<++[<]<[<]<+>>-[[>]>[>]>+++++++[-<++++++>]<+[<]<[<]<+>>-]>]<--[>+<++++++]>++>[>]+++++[->+++<]>[>+++>+++>+++>++++++>++++++>+++>++++>++++[<]>-]>+>->>+>+++>-->>++[<]<<[<]<<[<]>[[[>]>>[>]>>[>]<[->>+<<]<[<]<<[<]<<[<]>-]>[>]>>[>]>>[>]>>[-<<+[<]<+>>[>]>]<<[[->+<]<]>>[>]>[[-<+>]>]<<[<]<<[<]<<[<]>]>>>[>]>>[>]<[[-]<]>>>,[>+++++++[<------>-]+<-[>]>[<+<+>>>>]<<<-[>]>[<+<+>>>>]<<<-[>]>[<+<+>>>>]<<<-[>]>[<-<+++>>>>]<<<--------------[>]>[<++<+>>>>]<<<--[>]>[<-<+++++++>>>>]<<++++[-<------>]+<+[>]>[<++<+>>>>]<<<--[>]>[<-<+>>>>]<<-<[+]<[>]>,]>>>+<<<<-[<]>[-[<<]>[<+[>]>>[<]<<[>>+[<<[<]<<-[>>]<[>>>>[>]>+<<[<]<]<-[>>]<[>>>>[>]>-<<[<]<]<++[->>+<<]>>[>]>]<]<[<]>-<]>-[<<]>[<++[>]>>[<<]>[<<+[<<[<]>[-<<+>>]>--[<<]>[[>]>+<<[<]<]>+[<<]>[[>]>-<<[<]<]>+[>]>]]<<[<]>--<]>-[<<]>[[>]>>.<<<[<]<]>-[<<]>[[>]>>-<<<[<]<]>-[<<]>[[>]>>,<<<[<]<<<[<]<[<]>[[>]>[>]>>>[>]>>+<<<[<]<<<[<]<[<]>-]>[>]>[>]>>[<]<]>-[<<]>[[>]>>+<<<[<]<]>-[<<]>[[>]>>>[>>]>[<<<[<<]<+>>>[>>]>-]>[-]<<+[<[->>+<<]<]<[->>+<<]<[<]<]>-[<<]>[[>]>++[-->[-<<+>>]>]+<<-[++<<]<[->>>[>>]>+<<<[<<]<]<[<]<]<++++++++>>[+<<->>]>]>>[]
Probieren Sie es online! Die Eingabe hier ist ein einfaches cat-Programm (,[.,]
), das das Programm selbst ausgibt.
"Return 0" wird definiert, indem das Programm in einer Zelle mit dem Wert 0 beendet wird.
Eine unheilige Kombination aus zwei Programmen, die ich in der Vergangenheit geschrieben habe, einem Quine und einem Selbstinterpretierer. Der erste Abschnitt ist der Quine-Teil, der die Daten aufnimmt und das Band mit der Datengenerierung und anschließendem Quellcode auffüllt. Als nächstes kommt der Selbstinterpreter, der Ihr Programm übernimmt und ausführt. Dies ist so ziemlich eine unveränderte Kopie eines normalen Selbstinterpreters, mit der Ausnahme, dass die Eingabe nicht direkt erfolgt, sondern am Anfang des Datenabschnitts erfolgt und die Zelle auf 0 gesetzt wird, wenn keine weitere Eingabe erfolgt. Beenden Sie schließlich die aktuelle Zelle Ihres Programms und führen Sie es aus []
. Wenn der zurückgegebene Wert 0 war, endet mein Programm bei Null. Wenn es sich um etwas anderes handelt, wird eine Endlosschleife ausgeführt. Wenn Ihr Programm für immer läuft,Mein Programm wird für immer laufen.
Wie es funktioniert:
Teil 1: Datengenerierung
->++>++++> ....... >+++++>>>+++>>+++>>>++++>+++
Dieser Teil bildet den Datenabschnitt des Quines und ist mit 3270 Bytes bei weitem der größte Teil des Codes. Der Anfang -
ist eine Markierung für den Beginn der Daten. Jedes steht >+++
für ein Zeichen des Codes nach diesem Abschnitt.
Number of Pluses
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
> | < | + | ] | [ | - | , | . |
Teil 2: Generieren Sie den Datenabschnitt mit den Daten
+[<+]>
[
Add a right arrow
>[>]>[>]>(10++++++++++)[-<(6++++++)>]<++[<]<[<]
<+>>-
Add the right amount of pluses
[
[>]>[>]>(7+++++++)[-<(6++++++)>]<+[<]<[<]<+>>-
]
>
]
Add the beginning minus
<--[>+<++++++]>++
Hierbei werden die Daten aus Teil 1 verwendet, um die Zeichen, die zum Generieren der Daten verwendet werden, zum Codeabschnitt hinzuzufügen. Es fügt >
dem Ende des Codeabschnitts ein und dem Wert dieser Zelle viele Pluszeichen hinzu.
Teil 3: Generieren Sie den Rest des Codes mit den Daten
Initialises the 8 characters of brainfuck
>[>]+++++[->+++<]>[>+++>+++>+++>++++++>++++++>+++>++++>++++[<]>-]
>+>->>+>+++>-->>++[<]<<[<]<<[<]>
Tape looks like:
data 0 0 code 0 0 characters
Runs through the data destructively and adds the represented symbol to the code section
[
[
For each plus in this cell
Shift the gap in the characters over one
[>]>>[>]>>[>]<[->>+<<]
<[<]<<[<]<<[<]>-
]
Navigate to character
>[>]>>[>]>>[>]>>
Copy the character to the end of the code section
[-<<+[<]<+>>[>]>]
Shift the symbol section over one
<<[[->+<]<]
>>[>]>[[-<+>]>]
Navigate to next byte of data
<<[<]<<[<]<<[<]>
]
Remove characters
>>[>]>>[>]<[[-]<]
Zerstört den Datenabschnitt und fügt den Rest des Quellcodes zum Codeabschnitt hinzu
Teil 4: Eingegebenes Programm holen
>>>,
[
>(7+++++++)[<(6------)>-]+<-
[>]>
[plus <+<+>>>>]<<<
-[>]>
[comma <+<+>>>>]<<<
-[>]>
[minus <+<+>>>>]<<<
-[>]>
[dot <-<+++>>>>]<<<
(14--------------)[>]>
[left <++<+>>>>]<<<
--[>]>
[right <-<+++++++>>>>]<<
(29++++[-<------>]+<+)
[>]>
[start loop <++<+>>>>]<<<
--[>]>
[end loop <-<+>>>>]<<
-<[+]<[>]>,
]
Ruft das eingegebene Programm ab. Entfernt Nicht-Brainfuck-Zeichen und stellt jedes Zeichen mit einer Nummer dar:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
] | [ | . | - | , | + | > | < |
Stellt das Programmende mit dar 255
.
Teil 5: Interpretation der Eingabe
Initialise simulated tape
>>>+<<<<-
[<]>
[
-[<<]>
[end loop
co 0 0 0 e: _1 0 0 0 1 ?
Check if current cell is one
<+[>]>>[<]<<
co 0 0 1 e _1: 0 0 !0 1
or
co 0 0 1 e _1 0: 0 0 1
[ If current cell is one navigate to corresponding start loop
Create counter
>>+
[
co 0 0 de _1 0 c: !0 1
checks if next instruction is an end loop
<<[<]<<-
[>>]<
c !0 0: 0 de _1 0 c !0 1
or
c: 0 0 0 de _1 0 c !0 1
[>>>>[>]>+<<[<]<] Add one to counter if it is
checks if start loop
<-[>>]<
c !0 0: 0 de _1 0 c !0 1
or
c: 0 0 0 de _1 0 c !0 1
[>>>>[>]>-<<[<]<] Subtract one from counter if it is
c ? 0: 0 de _1 0 c !0 1
Adds two to counteract checks and move to the next instruction
<++[->>+<<]
>>[>]>
c 0 0 ode _1 0 c: !0 1
End on the counter
If the counter is 0 then we have reached the corresponding bracket
]
c 0 0 2 de _1 0 0: !0 1 0
<
]
c 0 0 1?2 de _1 0: 0 0 1 0
Subtract one from current instruction
This executes the start loop code next but that does nothing
<[<]>-<
]
>-[<<]>
[start loop
c 0 0 0 de: _1 0 0 ? 1
<++[>]>>[<<]>
c 0 0 2 de _1 0 0 0 1:
or
c 0 0 2 de _1 0 0: !0 1
[ If current cell is 0 navigate to corresponding end loop
Initialise counter
<<+
c 0 0 ode _1 0 c: 0 1
[ While counter is not 0
Transfer current instruction over (first instruction is guaranteed to be start loop)
<<[<]>[-<<+>>]>
co 0 0 de _1 0 c: 0 1
Check if start loop
--[<<]>
co 0 0: !0 e _1 0 c 0 1
or
co 0 0 0 e _1 0 c 0 1
[[>]>+<<[<]<] Add one to counter if so
checks if end loop
>+[<<]>
co 0 0: !0 e _1 0 c 0 1
or
co 0 0 0 e: _1 0 c 0 1
[[>]>-<<[<]<] Subtract one from counter if so
Add one to counteract checks and navigate to counter
>+[>]>
co 0 0 de _1 0 c: 0 1
End on counter
If counter is 0 then we have reached the corresponding end loop
]
co 0 1 e _1 0 0: 0 1
]
co 0 0 2?1 e _1 0 0: ? 1
Subtract two from the current instruction to bring it back up to the right value
<<[<]>--<
]
3 of these are pretty self explanatory
Navigate to the current cell and execute the instruction on it
>-[<<]>
[output
[>]>>.<<<[<]<
]
>-[<<]>
[minus
[>]>>-<<<[<]<
]
>-[<<]>
[input
Reset current cell
[>]>>, (no more input so this is set to 0)
co 0 0 0 e: _1 0 0 0: 1 b 1 a 0 d 1 e 1 f
Navigate to start of code section
<<<[<]<<<[<]<[<]>
d: ata 0 co 0 0 0 e _1 0 0 0 1 b
or
0: co 0 0 0 e _1
Transfer next instruction to current cell
[[>]>[>]>>>[>]>>+<<<[<]<<<[<]<[<]>-]
0: ata 0 co 0 0 0 e _1 0 0 d 1 b
or
0: co 0 0 0 e _1
Navigate back to the normal spot
>[>]>[>]>>[<]<
]
>-[<<]>
[plus
[>]>>+<<<[<]<
]
>-[<<]>
[right
Simulated tape looks like:
a b c: d e f
co 0 0 0 e: _1 0 0 c 1 b 1 a 0 d 1 e 1 f
Navigate to value of cell to the right
[>]>>>[>>]>
co 0 0 0 e _1 0 0 c 1 b 1 a 0 d: 1 e 1 f
Transfer it to temporary cell
[<<<[<<]<+>>>[>>]>-]
co 0 0 0 e _1 d 0 c 1 b 1 a 0 0: 1 e 1 f
Pop extra marker if it exists from the right cells and add one to the left
>[-]<<+
co 0 0 0 e _1 d 0 c 1 b 1 a 1: 0 0 e 1 f
Transfer all left cells over 2 cells
[<[->>+<<]<]<[->>+<<]
co 0 0 0 e _1 0: 0 d 1 c 1 b 1: a 0 e 1 f
Navigate back to normal spot
<[<]<
]
>-[<<]>
[left
Simulated tape looks like:
a b c: d e f
co 0 0 0: e _1 0 0 c 1 b 1 a 0 d 1 e 1 f
Add temporary marker
[>]>++
co 0 0 0 e _1 0 2: c 1 b 1 a 0 d 1 e 1 f
Remove temporary marker and transfer all left cells over two
[-->[-<<+>>]>]
co 0 0 0 e _1 c 0 b _1 a _1 0 0: d 1 e 1 f
Add marker to right cells remove marker from left cells and reset left cell's markers
+<<-[++<<]<
co 0 0 0 e _1 c: 0 b 1 a 0 0 1 d 1 e 1 f
Transfer current cell to to right cells
[->>>[>>]>+<<<[<<]<]
co 0 0 0 e _1 0: 0 b 1 a 0 c 1 d 1 e 1 f
Navigate back to normal spot
<[<]<
]
Add 8 to reverse checks
<(8++++++++)>>
Execute next instruction
[+<<->>]>
]
Interpretiert das Programm. Der einzige Unterschied zu einem normalen ist, dass die Eingabe am Anfang des Codeabschnitts statt der Eingabe erfolgt.
Teil 6: Halt, wenn return nicht 0 ist
>>[]
Navigieren Sie zur Endzelle Ihres Programms und führen Sie eine Endlosschleife aus, wenn die Rückgabe nicht 0 ist. Wenn sie 0 ist, beenden Sie die Schleife und beenden Sie sie bei derselben 0.
Testeingänge:
Gibt immer 0 zurück (hält an und gibt 0 zurück)
(empty program)
Gibt immer 1 zurück (läuft für immer)
+
Gibt alle Eingaben zusammen, Mod 256, zurück (gibt 211 zurück, läuft also für immer)
,[[->+<],]>
Gibt 0 zurück, wenn die letzten beiden Zeichen eines Codes eine Endlosschleife sind ( []
) ( Ihr Programm gibt 0 zurück, wenn es mein Programm gibt , daher stoppt mein Programm )
,[>,]>(9+++++++++)[-<(10++++++++++)>]<[-<-<->>]+<---[[-]>[-]<]<-[[-]>>[-]<<]>+>[-<->]<
Fun Fact für diejenigen, die noch lesen
Wenn es sich bei der Eingabe für dieses Programm um den Quellcode dieses Programms handelt, wird es rekursiv und erstellt wiederholt Selbstinterpreter, die dieses Programm ausführen, und gibt ihm dann dasselbe Programm erneut. Dies gibt mir einige interessante Ideen zum Erstellen von rekursiven Programmen in Brainfuck. Anstatt den Rückgabewert zu überprüfen und eine Endlosschleife wie in dieser Frage zu starten, kann der Rückgabewert gespeichert und bearbeitet werden. Ein einfaches Beispiel wäre ein Fakultätsprogramm
If cell1 == 0:
Get input into cell1
If cell1 == 1 or cell1 == 0:
Return 1
Else:
Initialise self-interpreter-quine function
Pass cell1-1 into cell1 of the function
Run function
Multiply cell1 by the return value
Return cell1
Dies ist natürlich eine völlig verrückte Art, Brainfuck zu codieren, da das Ausführen von rekursiven Selbstinterpretern die Laufzeit exponentiell erhöht.