_8
,%
;
"}{{+_5
"= %_!
= """{
;"{" )!
Se termine par une erreur de division par zéro (message d'erreur sur STDERR).
Essayez-le en ligne!
La disposition semble vraiment inefficace, mais je ne vois tout simplement pas de moyen de jouer au golf en ce moment.
Explication
Cette solution est basée sur l'astuce arithmétique de Dennis: prenez tous les codes de caractères modulo 8
, ajoutez une paire des deux extrémités et assurez-vous qu'elle est divisible par 5
.
Primaire 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.
- 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 parce qu'il y a un mur, l'IP prendra la direction opposée. L'IP se retourne également en cas d'impasse.
- Les chiffres sont traités en multipliant le haut de la pile principale par 10, puis en ajoutant le chiffre.
Le code commence par une petite boucle 2x2, dans le sens horaire, qui lit tous les modules d'entrée 8:
_ Push a 0.
8 Turn into 8.
% Modulo. The last three commands do nothing on the first iteration
and will take the last character code modulo 8 on further iterations.
, Read a character from STDIN or -1 at EOF. At EOF we will leave loop.
;
Jette maintenant le -1
. Nous entrons dans une autre boucle dans le sens des aiguilles d'une montre qui déplace le haut de la pile principale (c'est-à-dire le dernier caractère) vers le bas:
" No-op, does nothing.
} Move top of the stack over to aux. If it was at the bottom of the stack
this will expose a zero underneath and we leave the loop.
= Swap top of main with top of aux. The effect of the last two commands
together is to move the second-to-top stack element from main to aux.
" No-op.
Il y a maintenant un petit bit linéaire:
{{ Pull two characters from aux to main, i.e. the first and last (remaining)
characters of the input (mod 8).
+ Add them.
_5 Push 5.
% Modulo.
L'IP est maintenant à une jonction qui agit comme une branche pour tester la divisibilité par 5. Si le résultat du modulo est non nul, nous savons que l'entrée n'est pas un palindrome Watson-Crick et nous tournons vers l'est:
_ Push 0.
! Print it. The IP hits a dead end and turns around.
_ Push 0.
% Try to take modulo, but division by zero fails and the program terminates.
Sinon, nous devons continuer à vérifier le reste de l'entrée, afin que l'IP continue de se diriger vers le sud. Le {
tire sur le bas de l'entrée restante. Si nous avons épuisé l'entrée, ce sera un 0
(à partir du bas de aux ), et l'IP continue de se déplacer vers le sud:
) Increment 0 to 1.
! Print it. The IP hits a dead end and turns around.
) Increment 0 to 1.
{ Pull a zero over from aux, IP keeps moving north.
% Try to take modulo, but division by zero fails and the program terminates.
Sinon, il y a plus de caractères dans la chaîne à vérifier. L'IP se tourne vers l'ouest et se déplace dans la boucle 2x2 suivante (dans le sens des aiguilles d'une montre) qui se compose principalement de no-ops:
" No-op.
" No-op.
{ Pull one value over from aux. If it's the bottom of aux, this will be
zero and the IP will leave the loop eastward.
" No-op.
Après cette boucle, nous avons à nouveau l'entrée sur la pile principale, à l'exception de son premier et dernier caractère et avec un zéro en haut. Le ;
jette le 0
puis =
échange les sommets des piles, mais ceci est juste pour annuler le premier =
de la boucle, car nous entrons maintenant dans la boucle à un emplacement différent. Rincer et répéter.