Te encuentras en un tablero de ajedrez, como uno lo hace. Puedes ver la salida pero está muy lejos y prefieres no caminar todo el camino. Afortunadamente, algunos lugareños te han ofrecido un aventón. Un Caballero, una Torre, un Obispo y un Rey están dispuestos a llevarte a tu destino, pero al ver que este es un tablero de ajedrez, cada uno debe cumplir con las reglas del ajedrez en el camino a tu destino. Te gustaría salir de aquí lo antes posible, ¿qué oferta aceptas?
Tarea
Dado un tablero de ajedrez de tamaño y forma arbitraria y dos puntos en el tablero de ajedrez, saca la pieza de ajedrez que puede moverse entre las dos ubicaciones en el menor número de movimientos posible. Los tableros no serán necesariamente continuos, lo que significa que podría haber brechas entre las secciones del tablero. Cada una de las cuatro piezas (Rey, Torre, Caballero y Obispo) puede moverse de acuerdo con sus reglas estándar en ajedrez. La Reina y las piezas de peón se han dejado intencionalmente fuera de este desafío.
I / O
Puede tomar la entrada en cualquier formato razonable y también puede generar la salida en el formato que elija. Su entrada y salida debe ser autoconsistente. Si varias piezas pueden llegar al destino en el mismo número de movimientos, debe generar todas las piezas que pueden llegar allí en el mínimo tiempo posible. Si ninguna de las cuatro piezas puede llegar al final, puede generar algo siempre que sea distinto de todas las demás salidas posibles. Esto podría incluir no generar nada o arrojar un error.
Casos de prueba
Un cuadrado indica el punto de partida y un círculo indica el punto final.
obispo
Caballero
Rey
Torre
Rey, caballero
Ninguna
Respuestas:
Haskell ,
447439437432 bytesLlamar usando
g <board> <start> <end>
donde<board> :: [(Int, Int)]
,<start> :: (Int, Int)
y<end> :: (Int, Int)
. Devuelve una lista que contiene1
Knight,2
Rook,3
Bishop y4
King. Si no se encuentran soluciones, desborda constantemente la pila (eso cuenta como arrojar un error, ¿verdad?).La inspiración tomada de los capítulos de LYAH sobre Mónadas
(%)
es simplemente generalizada y de golfinMany
, con(&)
equivalente a(Control.Monad.<=<)
. Todo lo demás debería ser más o menos autoexplicativo.Probablemente se pueda jugar mucho más al golf, pero por ahora me he divertido lo suficiente.
Sin golf:
fuente
Mathematica,
326325 bytes¡Gracias a masterX224 por señalar un ahorro de bytes!
Define una función
f
de tomar tres argumentos:g
es una lista de pares ordenados de números enteros que representan el tablero, yw
yx
los pares ordenados que representan los cuadrados de inicio y fin. La salida es el subconjunto de{b, k, n, r}
(que representa obispo, rey, caballero y torre, respectivamente) que tienen una trayectoria de movimientos mínimos entre los dos cuadrados. Por ejemplo, el tercer caso de prueba es invocado porf[{{0, 0}, {1, 1}, {1, 2}, {0, 3}}, {0, 0}, {0, 3}]
y devuelve{k}
; los dos últimos casos de prueba regresan{k, n}
y{}
, respectivamente.La estrategia es traducir los cuadrados del tablero en vértices de un gráfico, donde los bordes están determinados por los movimientos de cada pieza, y luego usar rutinas de gráficos incorporados.
Versión más fácil de usar del código:
En la línea 3,
Select[g~Tuples~2, # - #2 & @@ # == d
encuentra todos los pares de vértices ordenados cuya diferencia es el vectord
;e
luego transforma cada par ordenado en un borde de gráfico no dirigido. Entonces,a
es una función que crea bordes entre todos los vértices que difieren en un vector fijo.Eso es suficiente para definir, en las líneas 4 y 5, el gráfico del rey
y@k
(que toma la unión de bordes generados por los vectores{1, 1}
,{-1, 1}
,{0, 1}
, y{-1, 0}
) y gráfico del caballeroy@n
(que hace lo mismo con{1, 2}
,{2, 1}
,{-2, 1}
, y{-1, 2}
).En la línea 7,
ConnectedComponents@a@#
toma uno de estos gráficos vecinos y luego encuentra sus componentes conectados; esto corresponde a agrupar todos los segmentos de línea de vértices en la dirección dada (para que una torre u alfil no tenga que moverse a través de ellos uno por uno). Luego,e@t@#
en la línea 6 coloca bordes entre cada par de vértices en el mismo componente conectado, que luego seFlatten
editan en un solo gráfico. Así, las líneas 6 a 8 definen la gráfica de la torre y la gráficay@r
del alfily@b
.Finalmente, las líneas 9 a 11 eligen los elementos
{b, k, n, r}
que producen el camino más corto entre los dos vértices objetivo.FindShortestPath
arrojará un error y volverá sin evaluar si un vértice objetivo no aparece en el gráfico (lo que sucederá si no emanan bordes), por loh@__ -> 0
que0
en su lugar usamos para regresar en esos casos. Y la falta de una ruta entre vértices válidos devuelve una lista de longitud0
, por lo queMin[z~Complement~{0}]
calcula la longitud de la ruta más pequeña que realmente existe, ignorando los casos negativos anteriores.fuente
f
en esa sesión, ¡pero debería haberla cambiado antes de enviarla!