En un reino lejano, una reina del ajedrez da un paseo diario a través de un camino en espiral, numerado del 1 al n
, sin preocuparse por seguir la espiral en sí, sino simplemente haciendo los movimientos de la reina como lo haría en un tablero de ajedrez. La reina es amada por sus súbditos, y toman nota de cada cuadro que visita en su camino. Dado que la reina puede comenzar su caminata en cualquier casilla y terminarla en cualquier casilla, ¿cuál es la caminata más corta que puede dar la reina?
El reto
Dada una espiral de enteros en una cuadrícula rectangular, escriba una función que devuelva uno de los caminos más cortos posibles (contados por el número de celdas recorridas) entre dos números en esta cuadrícula espiral usando los movimientos de una reina de ajedrez.
Por ejemplo, de 16
a 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
Algunos caminos posibles incluyen 16, 4, 2, 10, 25
y 16, 5, 1, 9, 25
.
Reglas
- La entrada será dos enteros positivos.
- La salida será una ruta de enteros (incluidos ambos puntos finales) a través de la espiral utilizando solo movimientos ortogonales y diagonales.
- La longitud de una ruta se cuenta por el número de celdas recorridas.
- Su respuesta puede ser un programa o una función.
- Este es el código de golf, por lo que gana el menor número de bytes.
Como siempre, si el problema no está claro, hágamelo saber. ¡Buena suerte y buen golf!
Casos de prueba
>>> 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
fuente
Respuestas:
APL (Dyalog Unicode) ,
5957 bytes SBCSPruébalo en línea!
-2 bytes gracias a @ngn.
Función anónima que acepta dos puntos finales como argumentos izquierdo y derecho.
Ungolfed y cómo funciona
La reina se mueve diagonalmente primero, por lo que es suficiente calcular previamente las coordenadas de cada número hasta
max(start,end)
.El algoritmo de generación de coordenadas se inspira en varias respuestas sobre el desafío relacionado , pero es ligeramente diferente de cualquiera de las respuestas existentes:
r=1 2 3 4 5 6 7 8 9 10
n=1 1 2 2 3 3 4 4 5 5
r
byn
.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
Luego, una vez que el vector de coordenadas
v
está listo, podemos convertir fácilmente entre el índice espiral y las coordenadas usandov[i]
yv⍳coord
(encontrar el primer índice decoord
inv
).fuente
(⍵⊃v)-⍺⊃v
->⊃⍵⍺-.⊃⊂
(⍺⌷v)
->v[⍺]
Mathematica
615530bytesEsto construye una cuadrícula de números, la convierte en un gráfico y luego encuentra una ruta más corta entre los dos números que se ingresaron.
Sin golf
numberSpiral
es de Mathworld Prime Spiral . Crea una espiral de n por n Ulam (sin resaltar los números primos).findPath
convierte la cuadrícula de números en un gráfico. Los bordes son movimientos de reina válidos en la cuadrícula de números.Ejemplos
{4,5}
{13,3,1,7,22}
{16,4,1,9,25}
El camino más corto de 80 a 1 contiene 5, no 6, vértices.
{80, 48, 24, 8, 1}
Golfed
fuente
Scala (830 bytes)
Construye la espiral en una matriz cuadrada en 2D usando cuatro funciones recursivas mutuamente. Otra búsqueda recursiva para construir la lista de rutas.
Sin golf
fuente
Rubí,
262218216 bytesEste es un puerto de mi respuesta de Python . Sugerencias de golf bienvenidas.
Editar: 45 bytes gracias a Jordan y sus sugerencias de
d=[0]*n=m*m;*e=c=0;*t=a
,.rect
,0<=>x
yx,y=(e[a]-g=e[b]).rect; t<<d[(g.real+x)*m+g.imag+y]
. Otro byte de(x+y*1i)
a(x+y.i)
.Sin golf:
fuente
q=
de su respuesta ya que no cuenta sus bytes.c=0;e=[c];t=[a]
se puede acortar a*e=c=0;*t=a
. Puede reemplazarz=e[a]-e[b];x,y=z.real,z.imag
conx,y=(e[a]-e[b]).rect
yx+=x<0?1:x>0?-1:0
conx+=0<=>x
(lo mismo paray
). Creo que eso lo reduce a 229 bytes.d
cond=[0]*m*m
, luego reemplaced[c.real][c.imag]
cond[c.real*m+c.imag]
yd[e[b].real+x][e[b].imag+y]
cond[(e[b].real+x)*m+e[b].imag+y]
.t<<d[(e[b].real+x)*m+e[b].imag+y]
se puede acortar au,v=e[b].rect;t<<d[(u+x)*m+v+y]
.d=[0]*m*m
ad=[0]*n=m*m
y(m*m).times
paran.times
. Eso es 219.x,y=(e[a]-e[b]).rect
ax,y=(e[a]-g=e[b]).rect
, borrandou,v=e[b].rect
y cambiandot<<d[(u+x)*m+v+y]
at<<d[(g.real+x)*g.imag+v+y]
(básicamente revertir mi penúltimo comentario).Python 3, 316 bytes
Esta respuesta mira las coordenadas de
a
yb
en la espiral (usando números complejos) y agrega los movimientos diagonales primero, luego los movimientos ortogonales.Sin golf:
fuente