`:_64/"32}
,` (3 :=-{
"`{"; _v2$ ;`3
"`".:@ ; ".5(`3.
< "" `^`;>
Une autre collaboration avec @ MartinBüttner et du côté le plus fou du spectre du Labyrinthe - pour la première fois, nous avons tous les quatre ^>v<
dans le même programme. Essayez-le en ligne!
Explication
L'algorithme général, qui s'exécute en boucle, est le suivant:
1. Read a char
2. If EOF:
3. Move all digits from auxiliary stack to main
4. Output all digits on main stack
5. Halt
Otherwise:
6. If char is a letter (c >= 64):
7. If random turns left:
8. Output char XOR 32
Otherwise:
9. Output char
Otherwise:
10. Shift char to auxiliary stack
11. If char is space (c-32 == 0):
12. Pull char back from auxiliary stack
13. Output underscore
Otherwise:
14. Continue loop
Pour garder l'explication compacte, voici à peu près comment chaque partie du programme correspond au pseudocode ci-dessus:
Voici les parties intéressantes.
Obtenir l'aléatoire dans le labyrinthe
Il n'y a qu'une seule façon d'obtenir l'aléatoire dans Labyrinth, et c'est quand l'IP essaie d'avancer mais 1) il n'y a ni chemin en avant ni en arrière et 2) il y a des chemins disponibles à gauche et à droite. Dans ce cas, l'IP choisit au hasard entre les routes gauche et droite.
Cela n'est possible qu'en utilisant les ^>v<
opérateurs, qui font apparaître n
et décaler la ligne / colonne n
de 1. Par exemple, le programme ( Essayez-le en ligne! )
" 1
""v!@
2
!@
renvoie 1 ou 2 de façon aléatoire, car la v
colonne décale de 0 (c'est-à-dire la colonne sur laquelle l'IP est activée) de 1, ce qui donne
"
""1!@
v
2!@
L'IP est orienté vers la droite et essaie d'avancer (le haut de la pile est nul) mais ne peut pas. Il ne peut pas non plus reculer, il choisit donc aléatoirement entre gauche ou droite.
Astuces de golf
Le programme démarre à partir du premier caractère dans l'ordre de lecture, ce que vous remarquerez en fait à l'étape 6. Cependant, le saut à partir d'une pile de labyrinthe vide donne 0, donc les étapes 10 et 14 se produisent, décalant un zéro vers la pile auxiliaire, ce qui est effectivement un no-op.
La pile principale est effectivement vide après chaque itération, ce qui nous permet de jouer la disposition du code en utilisant >
et <
sur les zéros implicites en bas. L' >
encapsule la ligne du bas de façon à ce que l'IP se déplace du bas à droite vers le bas à gauche, et le <
fait reculer la ligne. L'IP se déplace ensuite joyeusement vers le haut de la colonne de gauche pour continuer la boucle.
Les chiffres dans Labyrinth pop n
et push 10*n + <digit>
. De plus, les caractères sont pris modulo 256 avant d'être sortis. Mettre ces deux ensemble nous permet de sortir 95 (soulignement) en faisant `33
32 (espace), ce qui fonctionne parce que -3233 % 256 = 95
. Même s'il existe d'autres façons de transformer 32 en 95 ( ;95
étant la plus simple), travailler avec un nombre négatif ici nous permet de compacter un peu le code avec des virages à gauche.