7 , 410 caractères, 154 octets en codage 7, 0 lettres = score 154
55104010504200144434451510201304004220120504005434473340353241135014335450302052254241052253052244241052335452241114014241310052340435303052335442302052335500302052335430302052313340435303135014243241310335514052312241341351052302245341351525755102440304030434030421030442030424030455733413512410523142410523030523112411350143355142410523414252410523102410523002410523413342411145257551220304010420030455741403
Essayez-le en ligne!
Dans un défi qui n'aime pas utiliser des lettres, quelle meilleure langue à utiliser qu'une langue composée uniquement de chiffres?
Il s'agit d'un programme complet qui se termine par un plantage, il y a donc une sortie étrangère vers stderr, mais stdout est correct.
Explication
Un programme 7, lors de sa première itération, pousse simplement un certain nombre d'éléments dans la pile (car sur les 12 commandes qui existent dans 7, seulement 8 d'entre elles peuvent être représentées dans un programme source, et ces 8 sont spécialisés pour écrire du code pour pousser des structures de données particulières vers la pile). Ce programme n'utilise pas la 6
commande (qui est le moyen le plus simple de créer des structures imbriquées, mais a tendance à ne pas apparaître littéralement dans un programme source), donc ce ne sont que les 7
commandes qui déterminent la structure; 7
pousse un nouvel élément vide en haut de la pile (alors que les commandes 0
… 5
s'ajoutent simplement en haut de la pile). On peut donc ajouter des espaces au programme pour montrer sa structure:
551040105042001444344515102013040042201205040054344 7
33403532411350143354503020522542410522530522442410523354522411140142413100523
40435303052335442302052335500302052335430302052313340435303135014243241310335
514052312241341351052302245341351525 7
55102440304030434030421030442030424030455 7
33413512410523142410523030523112411350143355142410523414252410523102410523002
41052341334241114525 7
551220304010420030455 7
41403
Les éléments proches de la fin du programme sont poussés en dernier, ils sont donc en haut de la pile au début de la deuxième itération. Sur cette itération, et toutes les itérations futures, l'interpréteur 7 fait automatiquement une copie du haut de la pile et l'interprète comme un programme. Le littéral 41403
pousse le (non littéral, code en direct) 47463
(7 ont 12 commandes mais seulement 8 d'entre elles ont des noms; en tant que tel, j'utilise gras pour afficher le code et non gras pour montrer le littéral qui génère ce code, ce qui signifie c'est-à- 4
dire la commande qui s'ajoute 4
à l'élément de pile supérieur). Donc, le programme qui s'exécute sur la deuxième itération est 47463
. Voici ce que cela fait:
47463
4 Permutez les deux éléments de pile supérieurs, ajoutez un élément vide entre
7 Ajoutez un élément de pile vide en haut de la pile
4 Permutez les deux éléments supérieurs de pile, ajoutez un élément vide entre
6 Déterminez quelles commandes généreraient l'élément de pile supérieur;
ajoutez cela à l'élément ci-dessous (et ouvrez l'ancien haut de la pile)
3 Sortez l'élément de pile supérieur, éclatez l'élément ci-dessous
C'est plus facile à comprendre si nous regardons ce qui arrive à la pile:
- ... d c sur b un
47463
(code à exécuter: 47463
)
- ... d c b vider un (code à exécuter: )
47463
7463
- ... d c b vider un vide (code à exécuter: )
47463
463
- ... d c b vide vide vide un (code à exécuter: )
47463
63
- ... d c b vide vide " a " (code à exécuter: )
47463
3
- … D c b vide (code à exécuter: vide )
47463
En d'autres termes, nous prenons le haut de la pile a , déterminons quel code est le plus susceptible de l'avoir produit et éditons ce code. L'interpréteur 7 dépose automatiquement les éléments vides du haut de la pile à la fin d'une itération, nous nous retrouvons donc avec le 47463
dos au sommet de la pile, tout comme dans le programme d'origine. Il devrait être facile de voir ce qui se passe ensuite: nous finissons par parcourir chaque élément de la pile les uns après les autres, en les sortant tous, jusqu'à ce que la pile déborde et que le programme plante. Nous avons donc essentiellement créé une boucle de sortie simple qui examine le code source du programme pour déterminer ce qu'il faut sortir (nous ne sortons pas les structures de données qui ont été poussées vers la pile par notre 0
…5
commandes, nous recréons plutôt les commandes qui ont été utilisées en regardant quelles structures ont été créées et en les éditant). Ainsi, le premier élément de sortie de données est 551220304010420030455
(le code source qui génère l'élément de pile deuxième à partir du haut), le second est 3341351…114525
(le code source qui génère l'élément troisième pile à partir du haut), etc.
De toute évidence, cependant, ces morceaux de code source ne sont pas sortis non codés. 7 contient plusieurs langages spécifiques au domaine pour le codage de la sortie; une fois qu'une langue spécifique au domaine est choisie, elle reste utilisée jusqu'à ce qu'elle soit explicitement effacée, mais si aucune des langues n'a encore été choisie, le premier chiffre du code en sortie détermine laquelle des langues utiliser. Dans ce programme, seules deux langues sont utilisées: 551
et 3
.
551
est assez simple: il s'agit essentiellement de l'ancien code Baudot / télétype utilisé pour transmettre des lettres sur des télétypes, sous forme de jeu de caractères à 5 bits, mais modifié pour rendre toutes les lettres en minuscules. Ainsi, le premier morceau de code à sortir décode comme ceci:
551 22 03 04 01 04 20 03 04 55
c a SP e SP n a SP reset output format
Comme on peut le voir, nous ajustons chaque caractère en deux chiffres octaux, ce qui est un taux de compression assez décent. Des paires de chiffres dans la plage 0-5 nous offrent 36 possibilités, par opposition aux 32 possibilités dont Baudot a besoin, donc les quatre autres sont utilisés pour des commandes spéciales; dans ce cas, la 55
fin efface le format de sortie mémorisé, nous permettant d'utiliser un format différent pour la prochaine sortie que nous produisons.
3
est conceptuellement encore plus simple, mais avec une touche. L'idée de base est de prendre des groupes de trois chiffres (encore une fois, dans la plage 0-5, car ce sont les chiffres pour lesquels nous pouvons garantir que nous pouvons recréer le code source d'origine à partir de sa sortie), de les interpréter comme trois chiffres nombre en base 6, et juste le sortir comme un octet en binaire (nous permettant ainsi de sortir les caractères multi-octets dans la sortie souhaitée simplement en sortant plusieurs octets). La torsion, cependant, vient du fait qu'il n'y a que 216 nombres à trois chiffres (avec des zéros de tête possibles) dans la base 6, mais 256 octets possibles. 7 contourne cela en reliant des nombres de 332₆ = 128₁₀ à deux octets différents; 332
peut produire soit l'octet 128 ou 192, 333
soit l'octet 129 ou 193, et ainsi de suite, jusqu'à 515
ce que les sorties soit l'octet 191 ou 255.
Comment le programme sait-il laquelle des deux possibilités de sortie? Il est possible d'utiliser des triplets de chiffres de 520
haut en bas pour contrôler cela explicitement, mais dans ce programme, nous n'avons pas à: la valeur par défaut de 7 est de choisir tous les octets ambigus de telle sorte que la sortie soit valide UTF-8! Il s'avère qu'il y a toujours au plus une façon de le faire, donc tant que c'est UTF-8 que nous voulons (et nous le faisons dans ce cas), nous pouvons simplement le laisser ambigu et le programme fonctionne de toute façon.
La fin de chacune des 3…
sections est 525
, ce qui réinitialise le format de sortie, nous permettant de revenir à 551
la section suivante.
a
s - ou non, selon le nombre il faudrait des lettres, car 20 caractères est une très grosse pénalité (même si tout le reste est marqué par octets, ce n'est pas tout à fait bien défini ...)!