brainfuck , 6013 4877 4376 byte
Modifica: -1136 byte. Passato a un modo migliore di generare i dati per il quine
Modifica2: -501 byte. Ho rivisitato il mio interprete personale e l'ho ridotto di un paio di centinaia di byte
->++>++++>+>++>+++>>++++>>++++>>+++>>++++>>+++>>++>++>++>++>++>++>++>++>++>++>++++>+++++>+>++>++>++>++>++>++>>+++>+>++>++>++++>+>+++>+>++++>+>+++>+>++>>>+++++>++++>++++>>+++>>++++>>+++>>++>++>++>++>++>++>++>++++>+++++>+>++>++>++>++>++>++>>+++>+>++>++++>+>+++>+>++++>+>+++>+>++>>>+++++>+++>>+++>+>+++++>+++++>++++>>++>+>++>++>++>++>++>++>+++>>++>++>>++++>>+++>++>++>++>++>++>++++>+++++>>++>++>++>+>+++>>++++>>++>++>++>>++>++>++>>++>++>++>>++>++>++>++>++>++>>++>++>++>++>++>++>>++>++>++>>++>++>++>++>>++>++>++>++>++++>+>+++>>+++++>+++>>++>>+++++>>>++>>++>++>++>>+++++>+++++>>>++>++>++++>+>+++>+>+>++++>+>+++>+>+>++++>+>+++>>++++>++++>++++>>+++>>>++++>>+++>>>++++>>+++>+>++++>+++++>>>++>+>+>+++>+>++++>+>+++>+>+>++++>+>+++>+>+>++++>+>+++>>+++++>+++>>++++>>+++>>>++++>>+++>>>++++>>+++>>>++++>+++++>+>+>++>++++>+>+++>+>++>>>++++>>+++>>+++>+>+>++++>++++>+++++>>++>+>+++>+>+++>>>++++>>+++>>++++>++++>+++++>+>++>>+++>>+++>+>+>++++>+>+++>+>+>++++>+>+++>+>+>++++>+>+++>>+++>>>>++++>>+++>>>++++>>+++>+>++++>++++>+++++>+++>+>+++>>>>++++++>++++>>++>++>++>++>++>++>++>++++>+>+++++>+++++>+++++>+++++>+++++>+++++>>+++++>+++>++>+>+++++>++++>>+++>>++++>+>++>+>++>>>>>+++>+>+>+>+++++>++++>>+++>>++++>+>++>+>++>>>>>+++>+>+>+>+++++>++++>>+++>>++++>+>++>+>++>>>>>+++>+>+>+>+++++>++++>>+++>>++++>+>+++++>+>++>++>++>>>>>+++>+>+>+>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>++++>>+++>>++++>+>++>++>+>++>>>>>+++>+>+>+>+++++>+++++>++++>>+++>>++++>+>+++++>+>++>++>++>++>++>++>++>>>>>+++>+>+>++>++>++>++>++++>+++++>+>+++++>+++++>+++++>+++++>+++++>+++++>>+++>++>+>++>++++>>+++>>++++>+>++>++>+>++>>>>>+++>+>+>+>+++++>+++++>++++>>+++>>++++>+>+++++>+>++>>>>>+++>+>+>+++++>+>++++>++>+++>+>++++>>+++>>++++++>+++>>>>++>+>+>+>+>+++++>++++>+>+++>>++++>+++++>++++>+>+>+++>>++++>+>++>++++>>+++>>>++++>+>+++>+>+>++++>>>++>++++>+>+>++++>+>+++>+>+>+++++>++++>>>+++>+>++++>>>>>++++>>+++>>++>+>+>++++>+>+++>+>+++>+>+++++>++++>>>+++>+>++++>>>>>++++>>+++>>+++++>+>+>++++>+>+++>+>+++>+>++>++>++++>+++++>>>++>+>+>+++>>>++++>>+++>>+++>+>+++>+>++++>+>+++>>+++++>+>+++>>+++++>++++>+>+>+++>>++++>+>++>++>++++>>+++>>>++++>+>+>+++>>++++>+>+>++>++++>+>+>++++>+>+++>>++++>+++++>+>+>++>>>+++>>+++++>+++++>++++>+>+>+++>>++++>++++>>+++>>++>+>+>++++>+>+++>+>+++>>++>++++>+>+>+++>>++++>++++>>+++>>+++++>+>+>++++>+>+++>+>+++>>++>++++>>+++>>+++>+++>+>+>++++>+>+++>>+++++>+++++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>+++++++>+>+>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>+++++>+>+>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>++++++>+>+>+>++++>+>+++>+>+>+>++++>+>+++>+>++++>+>+++>>++++>++++>>+++>>++++>>+++>>>>++++>>+++>>>++>+>+>+>++++>+>+++>+>+>+>++++>+>+++>+>++++>+>+++>>+++++>+++>>++++>>+++>>++++>>+++>>>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>++>+>+>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>>++++>>>+++>>++++>+>+>+>++++>+>+>+++>+>++>>>>++++>>>+++>>+++++>+++>>++++>+++++>+++>+>+>++>++++>+>++++>+++++>>>++>+>+>+++>+>+++>+>++++>+++++>>>++>+>+>+++>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>++>++>++++>+++++>+++++>>++++>+++++>+>+>++>>>+++>>+++>++>+>+>+++++>++++>++>++>+>+>+++>+>++++>+++++>>>>++++>>>+++>>++>+>+>+>++++>+>+>+++>+>+++>+>++++>+>+++>+>+++>+>++>++>++>++>++>++>++>++>>>++++>++>+>+>+++++>>>+++>>+++>>>++++>++++[<+]>[>[>]>[>]>++++++++++[-<++++++>]<++[<]<[<]<+>>-[[>]>[>]>+++++++[-<++++++>]<+[<]<[<]<+>>-]>]<--[>+<++++++]>++>[>]+++++[->+++<]>[>+++>+++>+++>++++++>++++++>+++>++++>++++[<]>-]>+>->>+>+++>-->>++[<]<<[<]<<[<]>[[[>]>>[>]>>[>]<[->>+<<]<[<]<<[<]<<[<]>-]>[>]>>[>]>>[>]>>[-<<+[<]<+>>[>]>]<<[[->+<]<]>>[>]>[[-<+>]>]<<[<]<<[<]<<[<]>]>>>[>]>>[>]<[[-]<]>>>,[>+++++++[<------>-]+<-[>]>[<+<+>>>>]<<<-[>]>[<+<+>>>>]<<<-[>]>[<+<+>>>>]<<<-[>]>[<-<+++>>>>]<<<--------------[>]>[<++<+>>>>]<<<--[>]>[<-<+++++++>>>>]<<++++[-<------>]+<+[>]>[<++<+>>>>]<<<--[>]>[<-<+>>>>]<<-<[+]<[>]>,]>>>+<<<<-[<]>[-[<<]>[<+[>]>>[<]<<[>>+[<<[<]<<-[>>]<[>>>>[>]>+<<[<]<]<-[>>]<[>>>>[>]>-<<[<]<]<++[->>+<<]>>[>]>]<]<[<]>-<]>-[<<]>[<++[>]>>[<<]>[<<+[<<[<]>[-<<+>>]>--[<<]>[[>]>+<<[<]<]>+[<<]>[[>]>-<<[<]<]>+[>]>]]<<[<]>--<]>-[<<]>[[>]>>.<<<[<]<]>-[<<]>[[>]>>-<<<[<]<]>-[<<]>[[>]>>,<<<[<]<<<[<]<[<]>[[>]>[>]>>>[>]>>+<<<[<]<<<[<]<[<]>-]>[>]>[>]>>[<]<]>-[<<]>[[>]>>+<<<[<]<]>-[<<]>[[>]>>>[>>]>[<<<[<<]<+>>>[>>]>-]>[-]<<+[<[->>+<<]<]<[->>+<<]<[<]<]>-[<<]>[[>]>++[-->[-<<+>>]>]+<<-[++<<]<[->>>[>>]>+<<<[<<]<]<[<]<]<++++++++>>[+<<->>]>]>>[]
Provalo online! L'input qui è un semplice programma cat (,[.,]
) che stamperà il programma stesso.
"Return 0" viene definito terminando il programma su una cella con valore 0.
Una scellerata combinazione di due programmi che ho scritto in passato, un quine e un interprete di sé. La prima sezione è la parte quine, che prende i dati e popola il nastro con la generazione dei dati seguita dal codice sorgente. Il prossimo è l'auto-interprete, che prende il tuo programma e lo esegue. Questa è praticamente una copia invariata di un normale interprete automatico, tranne per il fatto che invece di prendere direttamente l'input, ottiene l'input dall'inizio della sezione dati, impostando la cella su 0 se non c'è più input. Infine, termina sulla cella corrente del programma ed esegui []
. Se il valore restituito era 0, il mio programma terminerà su zero. Se è qualcos'altro, eseguirà un ciclo infinito. Se il tuo programma funziona per sempre,il mio programma funzionerà per sempre.
Come funziona:
Parte 1: generazione di dati
->++>++++> ....... >+++++>>>+++>>+++>>>++++>+++
Questa parte costituisce la sezione dati del quine ed è di gran lunga la maggior parte del codice a 3270 byte. L'inizio -
è un marcatore per l'inizio dei dati. Ciascuno >+++
rappresenta un carattere del codice dopo questa sezione.
Number of Pluses
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
> | < | + | ] | [ | - | , | . |
Parte 2: genera la sezione dati utilizzando i dati
+[<+]>
[
Add a right arrow
>[>]>[>]>(10++++++++++)[-<(6++++++)>]<++[<]<[<]
<+>>-
Add the right amount of pluses
[
[>]>[>]>(7+++++++)[-<(6++++++)>]<+[<]<[<]<+>>-
]
>
]
Add the beginning minus
<--[>+<++++++]>++
Questo utilizza i dati della prima parte per aggiungere i caratteri utilizzati per generare i dati nella sezione del codice. Aggiunge un >
alla fine della sezione di codice e il valore di quella cella molti vantaggi.
Parte 3: genera il resto del codice utilizzando i dati
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
>>[>]>>[>]<[[-]<]
Distrugge la sezione dati e aggiunge il resto del codice sorgente alla sezione codice
Parte 4: Ottieni il programma inserito
>>>,
[
>(7+++++++)[<(6------)>-]+<-
[>]>
[plus <+<+>>>>]<<<
-[>]>
[comma <+<+>>>>]<<<
-[>]>
[minus <+<+>>>>]<<<
-[>]>
[dot <-<+++>>>>]<<<
(14--------------)[>]>
[left <++<+>>>>]<<<
--[>]>
[right <-<+++++++>>>>]<<
(29++++[-<------>]+<+)
[>]>
[start loop <++<+>>>>]<<<
--[>]>
[end loop <-<+>>>>]<<
-<[+]<[>]>,
]
Ottiene il programma inserito. Rimuove i caratteri non bloccati e rappresenta ogni personaggio con un numero:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
] | [ | . | - | , | + | > | < |
Rappresenta la fine del programma con 255
.
Parte 5: interpretazione dell'input
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
[+<<->>]>
]
Interpreta il programma. L'unica differenza rispetto a una normale è che l'input è preso dall'inizio della sezione di codice anziché l'input.
Parte 6: interrompere se il ritorno non è 0
>>[]
Passa alla cella finale del programma ed esegui un ciclo infinito se il ritorno non è 0. Se è 0, esci dal ciclo e termina sullo stesso 0.
Ingressi di prova:
Restituisce sempre 0 (si arresta e restituisce 0)
(empty program)
Restituisce sempre 1 (funziona per sempre)
+
Restituisce tutti gli input aggiunti insieme, mod 256 (restituisce 211, quindi funziona per sempre)
,[[->+<],]>
Restituisce 0 se gli ultimi due caratteri di un codice sono un ciclo infinito ( []
) (il tuo programma restituisce 0 quando viene dato il mio programma , quindi il mio programma si ferma)
,[>,]>(9+++++++++)[-<(10++++++++++)>]<[-<-<->>]+<---[[-]>[-]<]<-[[-]>>[-]<<]>+>[-<->]<
Fatto divertente per coloro che stanno ancora leggendo
Se l'input per questo programma è il codice sorgente di questo programma, allora ricomincerà a ripetersi, creando ripetutamente auto-interpreti che eseguono questo programma e poi gli restituiranno lo stesso programma. Questo mi dà alcune idee interessanti sulla creazione di programmi ricorsivi reali in brainfuck. Invece di verificare il valore restituito e avviare un ciclo infinito come in questa domanda, è possibile salvare e agire sul valore restituito. Un semplice esempio sarebbe un programma fattoriale che va
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
Naturalmente, questo è un modo completamente folle di codificare Brainfuck, dato che l'esecuzione di auto-interpreti ricorrenti aumenterà il tempo di esecuzione in modo esponenziale.