Dans un royaume lointain, une reine d'échecs fait une promenade quotidienne à travers un chemin en spirale, numéroté de 1 à n
, ne se souciant pas de suivre la spirale elle-même, mais faisant simplement les mouvements de la reine comme elle le ferait sur un échiquier. La reine est aimée de ses sujets, et ils notent chaque case qu'elle visite sur son chemin. Étant donné que la reine peut commencer sa marche sur n'importe quelle case et la terminer sur n'importe quelle case, quelle est la marche de la reine la plus courte qu'elle peut faire?
Le défi
Étant donné une spirale d'entiers sur une grille rectangulaire, écrivez une fonction qui renvoie l'une des plus courtes chemins possibles (compté par le nombre de cellules parcourues) entre deux nombres sur cette grille en spirale en utilisant les mouvements d'une reine d'échecs.
Par exemple, de 16
à 25
:
25 10 11 12 13
24 9 2 3 14
23 8 1 4 15
22 7 6 5 16
21 20 19 18 17
Certains chemins possibles incluent 16, 4, 2, 10, 25
et 16, 5, 1, 9, 25
.
Règles
- L'entrée sera constituée de deux entiers positifs.
- La sortie sera un chemin d'entiers (y compris les deux extrémités) à travers la spirale en utilisant uniquement des mouvements orthogonaux et diagonaux.
- La longueur d'un chemin est comptée par le nombre de cellules parcourues.
- Votre réponse peut être un programme ou une fonction.
- C'est le golf de code, donc le plus petit nombre d'octets gagne.
Comme toujours, si le problème n'est pas clair, faites-le moi savoir. Bonne chance et bon golf!
Cas de test
>>> queen_spiral(4, 5)
4, 5
>>> queen_spiral(13, 20)
13, 3, 1, 7, 20
>>> queen_spiral(14, 14)
14
>>> queen_spiral(10, 3)
10, 11, 3
>>> queen_spiral(16, 25)
16, 4, 2, 10, 25
>>> queen_spiral(80, 1)
80, 48, 24, 8, 1
la source
Réponses:
APL (Dyalog Unicode) ,
5957 octets SBCSEssayez-le en ligne!
-2 octets grâce à @ngn.
Fonction anonyme qui accepte deux points de terminaison comme arguments gauche et droit.
Non golfé et comment cela fonctionne
La reine se déplace en premier en diagonale, il suffit donc de pré-calculer les coordonnées de chaque nombre jusqu'à
max(start,end)
.L'algorithme générateur de coordonnées est inspiré de plusieurs réponses sur le défi associé , mais est légèrement différent de l'une des réponses existantes:
r=1 2 3 4 5 6 7 8 9 10
n=1 1 2 2 3 3 4 4 5 5
r
parn
.1 2 3 3 4 4 5 5 5 6 6 6 7 7 7 7 8 8 8 8 9 9 9 9 9 10 10 10 10 10
Ensuite, une fois que le vecteur de coordonnées
v
est prêt, nous pouvons facilement convertir entre l'index en spirale et les coordonnées à l'aide dev[i]
etv⍳coord
(trouver le premier indice decoord
inv
).la source
(⍵⊃v)-⍺⊃v
->⊃⍵⍺-.⊃⊂
(⍺⌷v)
->v[⍺]
Mathematica
615530 octetsCela construit une grille numérique, la convertit en graphique, puis trouve le chemin le plus court entre les deux nombres qui ont été saisis.
UnGolfed
numberSpiral
est de Mathworld Prime Spiral . Il crée une spirale Ulam n par n (sans mettre en évidence les nombres premiers).findPath
convertit la grille numérique en un graphique. Les bords sont des mouvements de reine valides sur la grille numérique.Exemples
{4,5}
{13,3,1,7,22}
{16,4,1,9,25}
Le chemin le plus court de 80 à 1 contient 5, et non 6, sommets.
{80, 48, 24, 8, 1}
Golfé
la source
Scala (830 octets)
Construit la spirale dans un tableau 2D carré en utilisant quatre fonctions mutuellement récursives. Une autre recherche récursive pour construire la liste des chemins.
Non golfé
la source
Ruby,
262218216 octetsCeci est un port de ma réponse Python . Suggestions de golf bienvenues.
Edit: 45 octets grâce à la Jordanie et leurs suggestions de
d=[0]*n=m*m;*e=c=0;*t=a
,.rect
,0<=>x
etx,y=(e[a]-g=e[b]).rect; t<<d[(g.real+x)*m+g.imag+y]
. Un autre octet de(x+y*1i)
à(x+y.i)
.Non golfé:
la source
q=
de votre réponse car vous ne comptez pas ses octets.c=0;e=[c];t=[a]
peut être raccourci*e=c=0;*t=a
. Vous pouvez remplacerz=e[a]-e[b];x,y=z.real,z.imag
parx,y=(e[a]-e[b]).rect
etx+=x<0?1:x>0?-1:0
parx+=0<=>x
(idem poury
). Je pense que cela ramène à 229 octets.d
pard=[0]*m*m
, puis remplacezd[c.real][c.imag]
pard[c.real*m+c.imag]
etd[e[b].real+x][e[b].imag+y]
pard[(e[b].real+x)*m+e[b].imag+y]
.t<<d[(e[b].real+x)*m+e[b].imag+y]
peut être raccourcieu,v=e[b].rect;t<<d[(u+x)*m+v+y]
.d=[0]*m*m
versd=[0]*n=m*m
et(m*m).times
versn.times
. C'est 219.x,y=(e[a]-e[b]).rect
enx,y=(e[a]-g=e[b]).rect
, en supprimantu,v=e[b].rect
et en changeantt<<d[(u+x)*m+v+y]
ent<<d[(g.real+x)*g.imag+v+y]
(en revenant essentiellement à mon avant-dernier commentaire).Python 3, 316 octets
Cette réponse examine les coordonnées de
a
etb
sur la spirale (en utilisant des nombres complexes) et ajoute d'abord les mouvements diagonaux, puis les mouvements orthogonaux.Non golfé:
la source