7 , 2 octets
7 utilise un jeu de caractères à 3 bits, mais prend les entrées emballées en octets (et selon la méta, les langues avec des jeux de caractères sous-octets sont comptées en utilisant des octets pour le fichier sur le disque ). Voici un xxd
vidage du programme:
00000000: 4cf4 L.
Lorsque vous donnez ce fichier à l'interpréteur 7, il affichera le programme suivant:
00000000: 4fa6 7f O..
qui à son tour sortira à nouveau le programme d'origine.
Alors qu'est-ce qui se passe ici? Il n'y a pas de lecture de source impliquée (en fait, je ne pense pas qu'il soit possible de lire la source en 7), bien que sans doute le programme triche d'une autre manière; laissez-moi savoir ce que vous pensez. Voici comment fonctionne le programme. (Notez que chaque commande 7 a deux variantes, dont certaines n'ont pas de nom et ne peuvent pas apparaître dans le programme d'origine. Il y a douze commandes au total, en six paires. J'utilise gras pour les commandes actives, non gras pour passif et dans les cas où la commande active n'a pas de nom, je lui donne le même nom que la commande passive correspondante et je compte sur les caractères gras pour les distinguer. Dans le cas où les deux sont nommés, par exemple, 7
qui est la variante active de 1
, chaque commande obtient son propre nom et le gras est juste une mise en évidence de la syntaxe.)
231 7 23 Programme original, déballé en octal
231 Poussez 237 sur la pile
23 Poussez 23 sur la pile
(implicite) ajouter une copie du haut de la pile au programme
2 Haut de la pile en double (actuellement 23 )
3 Haut de la sortie en sortie, pop deuxième élément de pile
À ce stade, l'interpréteur 7 voit que le haut de la pile contient des commandes ( 2
et 3
) qui ne sont pas représentables, il échappe donc au haut de la pile, produisant 723
(ce qui est). La première sortie de commande sélectionne le format de sortie; dans ce cas, c'est le format 7, "formatez la sortie de la même manière que le programme". Les commandes sont donc compressées en octets. Ensuite, le programme continue:
231 7 23 23
(implicite) ajouter une copie du haut de la pile au programme
2 Dupliquer le haut de la pile (actuellement 237 )
3 Sortir le haut de la pile, faire éclater le deuxième élément de la pile
7 Poussez un élément vide sur la pile
À ce stade, il n'y a que des éléments de pile vides sur la pile, donc le programme se ferme. Nous sortons 23
plus tôt. Si nous nous échappons 237
(et nous devons le faire, car il contient des commandes non représentables), nous obtenons 7231
. Cela obtient la sortie directement, ce qui rend la sortie finale du programme 237231
(formaté de la même manière que le programme, c'est-à-dire compressé en octets). Voilà 4fa67f
. (On peut noter que cela 1
était totalement inutile en termes d'affecter la sortie; la seule raison pour laquelle il est là est de rendre les deux programmes différents.)
La course se 237231
déroule presque exactement de la même manière; la différence est que l'inutile 1
s'exécute juste après la première impression (et l'élément vide est implicitement supprimé la deuxième fois que la fin actuelle du programme est atteinte). Encore une fois, les résultats 231
finissent par se produire eux-mêmes, les résultats 23
finissent par se produire précédés par un 7
, et nous obtenons 231723
, le programme original.
L'observateur pourrait noter que les deux programmes, bien qu'ils soient de la même longueur dans l'octal "natif" de la langue, sont de longueurs différentes sur le disque. En effet, un programme 7 peut être rempli avec un nombre arbitraire de 1 bits et le format compressé supprime le remplissage de fin. Voici comment l'encodage se produit:
2 3 1 7 2 3
010011001111010011(1...)
4 c f 4 padding
En d'autres termes, deux octets, 4C
F4
suffisent pour représenter le programme, c'est donc tout ce que j'ai utilisé.