:?
:
#/)
\ #
!"*@
"
Essayez-le en ligne!
Cela génère les résultats dans l'ordre C, B, A
séparé par des sauts de ligne.
Explication
Comme d'habitude, une courte introduction au Labyrinthe:
- Labyrinth possède deux piles d'entiers de précision arbitraire, principale et auxiliaire (iliaire), qui sont initialement remplis d'une quantité infinie (implicite) de zéros. Nous n'utiliserons que main pour cette réponse.
- Le code source ressemble à un labyrinthe, où le pointeur d'instruction (IP) suit les couloirs quand il le peut (même dans les coins). Le code commence au premier caractère valide dans l'ordre de lecture, c'est-à-dire dans le coin supérieur gauche dans ce cas. Lorsque l'IP arrive à n'importe quelle forme de jonction (c'est-à-dire plusieurs cellules adjacentes en plus de celle dont elle est issue), elle choisira une direction basée sur le haut de la pile principale. Les règles de base sont les suivantes: tourner à gauche lorsque négatif, continuer à avancer à zéro, tourner à droite lorsqu'il est positif. Et lorsque l'un d'eux n'est pas possible car il y a un mur, l'IP prendra la direction opposée. L'IP se retourne également en cas d'impasse.
Malgré les deux non-ops ("
) qui rendent la mise en page un peu inutile, je suis assez satisfait de cette solution, car son flux de contrôle est en fait assez subtil.
L'IP commence dans le coin supérieur gauche à :
droite. Il atteindra immédiatement une impasse sur le ?
et se retournera, de sorte que le programme démarre réellement avec ce morceau de code linéaire:
: Duplicate top of main stack. This will duplicate one of the implicit zeros
at the bottom. While this may seem like a no-op it actually increases
the stack depth to 1, because the duplicated zero is *explicit*.
? Read n and push it onto main.
: Duplicate.
: Duplicate.
Cela signifie que nous avons maintenant trois exemplaires de n
sur la pile principale, mais sa profondeur est 4
. C'est pratique car cela signifie que nous pouvons la profondeur de la pile pour récupérer le multiplicateur actuel tout en travaillant à travers les copies de l'entrée.
L'IP entre désormais dans une boucle 3x3 (dans le sens des aiguilles d'une montre). Notez que#
, ce qui pousse la profondeur de pile, poussera toujours une valeur positive telle que nous savons que l'IP se tournera toujours vers l'est à ce point.
Le corps de la boucle est le suivant:
# Push the stack depth, i.e. the current multiplier k.
/ Compute n / k (rounding down).
) Increment.
# Push the stack depth again (this is still k).
* Multiply. So we've now computed (n/k+1)*k, which is the number
we're looking for. Note that this number is always positive so
we're guaranteed that the IP turns west to continue the loop.
" No-op.
! Print result. If we've still got copies of n left, the top of the
stack is positive, so the IP turns north and does another round.
Otherwise, see below...
\ Print a linefeed.
Then we enter the next loop iteration.
Après que la boucle a été parcourue (jusqu'à !
) trois fois, toutes les copies den
sont utilisées et le zéro en dessous est révélé. En raison "
du bas (qui semble autrement assez inutile), cette position est une jonction. Cela signifie qu'avec un zéro au-dessus de la pile, l'IP essaie d'aller tout droit (ouest), mais parce qu'il y a un mur, il fait un virage à 180 degrés et recule vers l'est comme s'il avait atteint une impasse.
Par conséquent, le bit suivant est maintenant exécuté:
" No-op.
* Multiply two zeros on top of the stack, i.e. also a no-op.
The top of the stack is now still zero, so the IP keeps moving east.
@ Terminate the program.
C B A
) si cela est clairement spécifié dans la réponse?