brainfuck , 6013 4877 4376 octets
Modifier: -1136 octets. Passé à une meilleure façon de générer les données pour le quine
Edit2: -501 octets. Revisité mon auto-interprète et coupé quelques centaines d'octets
->++>++++>+>++>+++>>++++>>++++>>+++>>++++>>+++>>++>++>++>++>++>++>++>++>++>++>++++>+++++>+>++>++>++>++>++>++>>+++>+>++>++>++++>+>+++>+>++++>+>+++>+>++>>>+++++>++++>++++>>+++>>++++>>+++>>++>++>++>++>++>++>++>++++>+++++>+>++>++>++>++>++>++>>+++>+>++>++++>+>+++>+>++++>+>+++>+>++>>>+++++>+++>>+++>+>+++++>+++++>++++>>++>+>++>++>++>++>++>++>+++>>++>++>>++++>>+++>++>++>++>++>++>++++>+++++>>++>++>++>+>+++>>++++>>++>++>++>>++>++>++>>++>++>++>>++>++>++>++>++>++>>++>++>++>++>++>++>>++>++>++>>++>++>++>++>>++>++>++>++>++++>+>+++>>+++++>+++>>++>>+++++>>>++>>++>++>++>>+++++>+++++>>>++>++>++++>+>+++>+>+>++++>+>+++>+>+>++++>+>+++>>++++>++++>++++>>+++>>>++++>>+++>>>++++>>+++>+>++++>+++++>>>++>+>+>+++>+>++++>+>+++>+>+>++++>+>+++>+>+>++++>+>+++>>+++++>+++>>++++>>+++>>>++++>>+++>>>++++>>+++>>>++++>+++++>+>+>++>++++>+>+++>+>++>>>++++>>+++>>+++>+>+>++++>++++>+++++>>++>+>+++>+>+++>>>++++>>+++>>++++>++++>+++++>+>++>>+++>>+++>+>+>++++>+>+++>+>+>++++>+>+++>+>+>++++>+>+++>>+++>>>>++++>>+++>>>++++>>+++>+>++++>++++>+++++>+++>+>+++>>>>++++++>++++>>++>++>++>++>++>++>++>++++>+>+++++>+++++>+++++>+++++>+++++>+++++>>+++++>+++>++>+>+++++>++++>>+++>>++++>+>++>+>++>>>>>+++>+>+>+>+++++>++++>>+++>>++++>+>++>+>++>>>>>+++>+>+>+>+++++>++++>>+++>>++++>+>++>+>++>>>>>+++>+>+>+>+++++>++++>>+++>>++++>+>+++++>+>++>++>++>>>>>+++>+>+>+>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>++++>>+++>>++++>+>++>++>+>++>>>>>+++>+>+>+>+++++>+++++>++++>>+++>>++++>+>+++++>+>++>++>++>++>++>++>++>>>>>+++>+>+>++>++>++>++>++++>+++++>+>+++++>+++++>+++++>+++++>+++++>+++++>>+++>++>+>++>++++>>+++>>++++>+>++>++>+>++>>>>>+++>+>+>+>+++++>+++++>++++>>+++>>++++>+>+++++>+>++>>>>>+++>+>+>+++++>+>++++>++>+++>+>++++>>+++>>++++++>+++>>>>++>+>+>+>+>+++++>++++>+>+++>>++++>+++++>++++>+>+>+++>>++++>+>++>++++>>+++>>>++++>+>+++>+>+>++++>>>++>++++>+>+>++++>+>+++>+>+>+++++>++++>>>+++>+>++++>>>>>++++>>+++>>++>+>+>++++>+>+++>+>+++>+>+++++>++++>>>+++>+>++++>>>>>++++>>+++>>+++++>+>+>++++>+>+++>+>+++>+>++>++>++++>+++++>>>++>+>+>+++>>>++++>>+++>>+++>+>+++>+>++++>+>+++>>+++++>+>+++>>+++++>++++>+>+>+++>>++++>+>++>++>++++>>+++>>>++++>+>+>+++>>++++>+>+>++>++++>+>+>++++>+>+++>>++++>+++++>+>+>++>>>+++>>+++++>+++++>++++>+>+>+++>>++++>++++>>+++>>++>+>+>++++>+>+++>+>+++>>++>++++>+>+>+++>>++++>++++>>+++>>+++++>+>+>++++>+>+++>+>+++>>++>++++>>+++>>+++>+++>+>+>++++>+>+++>>+++++>+++++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>+++++++>+>+>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>+++++>+>+>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>++++++>+>+>+>++++>+>+++>+>+>+>++++>+>+++>+>++++>+>+++>>++++>++++>>+++>>++++>>+++>>>>++++>>+++>>>++>+>+>+>++++>+>+++>+>+>+>++++>+>+++>+>++++>+>+++>>+++++>+++>>++++>>+++>>++++>>+++>>>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>++>+>+>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>>++++>>>+++>>++++>+>+>+>++++>+>+>+++>+>++>>>>++++>>>+++>>+++++>+++>>++++>+++++>+++>+>+>++>++++>+>++++>+++++>>>++>+>+>+++>+>+++>+>++++>+++++>>>++>+>+>+++>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>++>++>++++>+++++>+++++>>++++>+++++>+>+>++>>>+++>>+++>++>+>+>+++++>++++>++>++>+>+>+++>+>++++>+++++>>>>++++>>>+++>>++>+>+>+>++++>+>+>+++>+>+++>+>++++>+>+++>+>+++>+>++>++>++>++>++>++>++>++>>>++++>++>+>+>+++++>>>+++>>+++>>>++++>++++[<+]>[>[>]>[>]>++++++++++[-<++++++>]<++[<]<[<]<+>>-[[>]>[>]>+++++++[-<++++++>]<+[<]<[<]<+>>-]>]<--[>+<++++++]>++>[>]+++++[->+++<]>[>+++>+++>+++>++++++>++++++>+++>++++>++++[<]>-]>+>->>+>+++>-->>++[<]<<[<]<<[<]>[[[>]>>[>]>>[>]<[->>+<<]<[<]<<[<]<<[<]>-]>[>]>>[>]>>[>]>>[-<<+[<]<+>>[>]>]<<[[->+<]<]>>[>]>[[-<+>]>]<<[<]<<[<]<<[<]>]>>>[>]>>[>]<[[-]<]>>>,[>+++++++[<------>-]+<-[>]>[<+<+>>>>]<<<-[>]>[<+<+>>>>]<<<-[>]>[<+<+>>>>]<<<-[>]>[<-<+++>>>>]<<<--------------[>]>[<++<+>>>>]<<<--[>]>[<-<+++++++>>>>]<<++++[-<------>]+<+[>]>[<++<+>>>>]<<<--[>]>[<-<+>>>>]<<-<[+]<[>]>,]>>>+<<<<-[<]>[-[<<]>[<+[>]>>[<]<<[>>+[<<[<]<<-[>>]<[>>>>[>]>+<<[<]<]<-[>>]<[>>>>[>]>-<<[<]<]<++[->>+<<]>>[>]>]<]<[<]>-<]>-[<<]>[<++[>]>>[<<]>[<<+[<<[<]>[-<<+>>]>--[<<]>[[>]>+<<[<]<]>+[<<]>[[>]>-<<[<]<]>+[>]>]]<<[<]>--<]>-[<<]>[[>]>>.<<<[<]<]>-[<<]>[[>]>>-<<<[<]<]>-[<<]>[[>]>>,<<<[<]<<<[<]<[<]>[[>]>[>]>>>[>]>>+<<<[<]<<<[<]<[<]>-]>[>]>[>]>>[<]<]>-[<<]>[[>]>>+<<<[<]<]>-[<<]>[[>]>>>[>>]>[<<<[<<]<+>>>[>>]>-]>[-]<<+[<[->>+<<]<]<[->>+<<]<[<]<]>-[<<]>[[>]>++[-->[-<<+>>]>]+<<-[++<<]<[->>>[>>]>+<<<[<<]<]<[<]<]<++++++++>>[+<<->>]>]>>[]
Essayez-le en ligne! L'entrée ici est un simple programme cat (,[.,]
) qui imprimera le programme lui-même.
"Retour 0" est défini en terminant le programme sur une cellule avec la valeur 0.
Une combinaison impie de deux programmes que j'ai écrits dans le passé, un quine et un auto-interprète. La première section est la partie quine, qui prend les données et remplit la bande avec la génération de données suivie du code source. Vient ensuite l'auto-interprète, qui prend votre programme et l'exécute. Il s'agit à peu près d'une copie inchangée d'un auto-interprète normal, sauf qu'au lieu de prendre directement une entrée, il obtient une entrée depuis le début de la section de données, définissant la cellule sur 0 s'il n'y a plus d'entrée. Enfin, terminez sur la cellule actuelle de votre programme et exécutez []
. Si la valeur retournée était 0, mon programme se terminera sur zéro. Si c'est autre chose, il exécutera une boucle infinie. Si votre programme fonctionne pour toujours,mon programme fonctionnera pour toujours.
Comment ça marche:
Partie 1: Génération de données
->++>++++> ....... >+++++>>>+++>>+++>>>++++>+++
Cette partie constitue la section de données du quine, et est de loin la majorité du code à 3270 octets. Le début -
est un marqueur pour le début des données. Chacun >+++
représente un caractère du code après cette section.
Number of Pluses
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
> | < | + | ] | [ | - | , | . |
Partie 2: générer la section de données à l'aide des données
+[<+]>
[
Add a right arrow
>[>]>[>]>(10++++++++++)[-<(6++++++)>]<++[<]<[<]
<+>>-
Add the right amount of pluses
[
[>]>[>]>(7+++++++)[-<(6++++++)>]<+[<]<[<]<+>>-
]
>
]
Add the beginning minus
<--[>+<++++++]>++
Cela utilise les données de la première partie pour ajouter les caractères utilisés pour générer les données dans la section de code. Il ajoute un >
à la fin de la section de code et la valeur de cette cellule de nombreux avantages.
Partie 3: générer le reste du code en utilisant les données
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
>>[>]>>[>]<[[-]<]
Détruit la section de données et ajoute le reste du code source à la section de code
Partie 4: Obtenez le programme saisi
>>>,
[
>(7+++++++)[<(6------)>-]+<-
[>]>
[plus <+<+>>>>]<<<
-[>]>
[comma <+<+>>>>]<<<
-[>]>
[minus <+<+>>>>]<<<
-[>]>
[dot <-<+++>>>>]<<<
(14--------------)[>]>
[left <++<+>>>>]<<<
--[>]>
[right <-<+++++++>>>>]<<
(29++++[-<------>]+<+)
[>]>
[start loop <++<+>>>>]<<<
--[>]>
[end loop <-<+>>>>]<<
-<[+]<[>]>,
]
Obtient le programme entré. Supprime les caractères non-brainfuck et représente chaque personnage avec un nombre:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
] | [ | . | - | , | + | > | < |
Représente la fin du programme avec 255
.
Partie 5: Interpréter l'entrée
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
[+<<->>]>
]
Interprète le programme. La seule différence par rapport à une normale est que l'entrée est prise depuis le début de la section de code au lieu de l'entrée.
Partie 6: Arrêtez si le retour n'est pas 0
>>[]
Accédez à la dernière cellule de votre programme et exécutez une boucle infinie si le retour n'est pas 0. S'il est 0, quittez la boucle et terminez sur ce même 0.
Entrées de test:
Retourne toujours 0 (arrête et retourne 0)
(empty program)
Renvoie toujours 1 (fonctionne pour toujours)
+
Renvoie toutes les entrées ajoutées ensemble, mod 256 (renvoie 211, donc il fonctionne pour toujours)
,[[->+<],]>
Retourne 0 si les deux derniers caractères d'un code sont une boucle infinie ( []
) ( votre programme retourne 0 quand on me donne mon programme , donc mon programme s'arrête)
,[>,]>(9+++++++++)[-<(10++++++++++)>]<[-<-<->>]+<---[[-]>[-]<]<-[[-]>>[-]<<]>+>[-<->]<
Fait amusant pour ceux qui lisent encore
Si l'entrée de ce programme est le code source de ce programme, alors il commencera à se reproduire, créant à plusieurs reprises des auto-interprètes qui exécutent ce programme et lui donneront ensuite le même programme. Cela me donne quelques idées intéressantes sur la création de programmes récursifs réels dans brainfuck. Au lieu de vérifier la valeur de retour et de démarrer une boucle infinie comme dans cette question, la valeur de retour peut être enregistrée et traitée. Un exemple simple serait un programme factoriel qui 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
Bien sûr, c'est une façon complètement folle de coder le brainfuck, étant donné que l'exécution d'auto-interprètes récursifs augmentera le temps d'exécution de manière exponentielle.