Ce défi est un prix pour ais523 pour avoir remporté la catégorie " Recrue de l'année " dans " Best of PPCG 2016 ". Toutes nos félicitations!
BackFlip est un langage de programmation ésotérique créé par l'utilisateur ais523 , qui a créé bien plus de 30 autres esolangs intéressants .
BackFlip est un langage 2D comme Befunge ou > <> où le pointeur d'instruction traverse une grille de texte (le programme), se déplaçant vers le haut, le bas, la gauche et la droite, changeant de direction en fonction du caractère sur lequel il se trouve. De manière critique, la grille d'un programme BackFlip change au fur et à mesure de sa traversée, un peu comme la fourmi de Langton .
Pour ce défi, vous pouvez supposer qu'un programme BackFlip est toujours une grille rectangulaire de texte (toutes les lignes de la même longueur), de taille 1 × 1 au minimum, contenant uniquement les caractères ./\<>^V
. ( .
est utilisé pour la visibilité plutôt que pour l'espace.) Sémantiquement, le BackFlip que nous utiliserons ici est identique à la spécification d'origine .
Le pointeur d'instruction (IP) dans BackFlip commence toujours juste à gauche du coin supérieur gauche du programme, se dirigeant vers la droite. Il existe trois types de commandes qu'il peut rencontrer:
.
est un no-op. L'IP continue dans la direction où il allait. Le no-op reste un no-op./
et\
sont des miroirs. Ils reflètent l'IP dans la direction indiquée par leur angle, puis ils se transforment en l'autre type de miroir .- Par exemple, si les têtes IP sont laissées dans un
\
, il commence à se déplacer vers le haut au lieu de gauche et le\
devient a/
.
- Par exemple, si les têtes IP sont laissées dans un
<
,>
,^
EtV
sont des flèches. Ils redirigent l'IP vers la direction dans laquelle ils pointent, puis ils se transforment en une flèche qui pointe dans la direction d'où provient l'IP (opposée à la direction dans laquelle l'IP se déplaçait) .- Par exemple, si l'IP se dirige vers le bas
>
, il commence à se déplacer vers la droite plutôt que vers le bas et>
devient un^
car c'est la direction d'où provient l'IP.
- Par exemple, si l'IP se dirige vers le bas
Un programme BackFlip se termine lorsque l'IP sort des limites, c'est-à-dire sort du réseau. Il s'avère que tous les programmes BackFlip finissent par se terminer car les boucles infinies sont impossibles. (Vous pouvez supposer que c'est vrai.)
Votre objectif dans ce défi est d'écrire un programme ou une fonction qui prend un programme BackFlip et génère le nombre de mouvements que le pointeur d'instruction prend avant la fin du programme. Autrement dit, combien d'étapes l'IP prend-il au cours de l'exécution d'un programme? Cela comprend l'étape initiale sur la grille et l'étape finale hors de celle-ci.
Par exemple, le pointeur d'instruction prend 5 étapes dans la grille triviale ....
:
.... <- empty 4×1 grid
012345 <- step number of the IP
Donc, la sortie ....
est 5
.
Dans la grille 4 × 2 plus complexe
\...
\.><
l'IP quitte la grille à sa 9e étape, donc la sortie est 9
:
step grid IP position (@)
0 \... @....
\.>< ....
1 \... @...
\.>< ....
2 /... ....
\.>< @...
3 /... ....
/.>< .@..
4 /... ....
/.>< ..@.
5 /... ....
/.<< ...@
6 /... ....
/.<< ..@.
7 /... ....
/.>< .@..
8 /... ....
/.>< @...
9 /... ....
\.>< ....
@
Le code le plus court en octets gagne.
Vous pouvez prendre l'entrée comme un tableau de lignes ou une matrice de caractères au lieu d'une chaîne multiligne si vous le souhaitez, mais vous devez utiliser les caractères ./\<>^V
(pas les opcodes entiers). Vous pouvez utiliser l'espace au lieu de .
si vous préférez. C'est bien si des caractères comme \
doivent être échappés en entrée. La sortie est toujours un entier plus d'un.
Cas de test
....
5
\...
\.><
9
.
2
..
3
.
.
2
\
2
^
2
.^.
3
<.
2
\\
\/
7
>V
^<
6
>\
>/
6
\><
2
\><
\><
7
\><
\><
\><
12
\.V.
\.\<
5
\.V.
\./<
9
V./\
V./\
>./<
..\/
14
\V..
.^..
\/><
.V..
.^..
20
\.V.V.
\./.\<
.>\<..
..^.^.
31
\.V.V.V.
\./>/.\<
.>\>\<..
..^.^.^.
69
\.V.V.V.V.
\./>/>/.\<
.>\>\>\<..
..^.^.^.^.
145
\.V.V.V.V.V.V.V.V.V.V.
\./>/>/>/>/>/>/>/>/.\<
.>\>\>\>\>\>\>\>\>\<..
..^.^.^.^.^.^.^.^.^.^.
9721
la source
/
, l'IP montera et que vous vous dirigerez vers l'intérieur,/
l'IP ira à droite, comme s'il s'agissait d'une balle rebondissant sur un mur. (Mais souvenez-vous des/
changements apportés à la barre oblique inversée après que l'IP le touche.)Réponses:
JavaScript (ES6), 158 octets
Développé indépendamment de la réponse de @ tsh bien que remarquablement similaire.
Le mappage des directions
^<v>
aux entiers 0-3 est régi par le fait que.search('^')
renvoie 0 car il^
s'agit d'un métacaractère d'expression régulière.la source
Haskell ,
333325 octetsÉDITER:
f
point et fusionnéb
.b
prend une liste deString
s et retourne unInteger
.Essayez-le en ligne!
Comment ça fonctionne
C a
est un type de données utilisé car Haskell ne permet pas qu'un type soit récursif sans le déclarer explicitement.C
est également un constructeur d'encapsulation etc
sa fonction de dépliage correspondante. Il n'est utilisé qu'aveca=[Int]
.C [Int]
représente une commande de cellule, en tant que fonction qui prend un[Int]
argument direction ( ) et renvoie une paire d'une nouvelle direction et une nouvelleC [Int]
valeur.b
est la fonction principale. Il convertit chaque caractère enC
valeur, puis il appelle#
.g
est la grille sous forme de liste de chaînes.\
doit être échappé et qu'il s'agit du caractère le plus long à mentionner, son résultat est plutôt utilisé comme valeur par défaut pour la recherche de liste.#
exécute la simulation principale, vérifie les limites&
et génère de nouvelles grilles avec?
.[y,x]
est la position actuelle,d
la direction actuelle etg
la grille actuelle.[f,e]
est la prochaine direction, etn
est une paire de celle-ci et la prochaine grille.l&i
vérifie si l'indexi
est hors limites pour la listel
. (Il revientTrue
pour hors des limites, car cela évite une condition de garde factice dans#
.)f(l!!i)==(d,x)
,(f?i)l==(d,m)
oùm
est la listel
avec lei
e élément remplacé parx
.(?i)
c'est un objectif plus général, se concentrant sur le ième élément d'une liste, dans ce cas utilisé avec l'(,) [Int]
instance de foncteur.n
est la fonction représentant un point.a v
est une fonction représentant une flèche dans le sensv
.m s
est une fonction représentant un miroir;s==1
pour\\
ets==-1
pour/
.la source
JavaScript, 172 octets
Mais je ne peux pas tester le dernier testcase car j'ai eu un débordement de pile sur ma machine. (devrait fonctionner s'il existe une machine avec un vérin plus grand)
Nous utilisons un nombre pour la direction:
Soit
d
le numéro de direction ...Laissez -
(x, y)
être la position actuelle, la position suivante est:x+(t&1&&t-2)
,y+(~t&1&&t-1)
Remarque:
La fonction prend un paramètre au format suivant:
Testez-le ici
la source
Uncaught RangeError: Maximum call stack size exceeded
avec 16 Go de RAM.var
déclarations lui font passer le dernier testcase (l'interpréteur js optimise les appels en mode strict)C,
232221 octetsPrend l'entrée dans le premier argument, imprime le résultat. Nécessite que l'entrée contienne au moins 1 nouvelle ligne (donc s'il n'y a qu'une seule ligne, elle doit se terminer par une nouvelle ligne)
Exemple d'utilisation:
Panne:
la source
Python 3 , 286 octets
[f () prend l'entrée sous la forme de
{(0,0):'/',(0,1):'.'}
donc j'ai également écrit une fonction g () pour convertir un tableau de lignes dans cette forme]Essayez-le en ligne!
la source