Dibujar el triángulo de Sierpinski se ha hecho a la muerte . Sin embargo, hay otras cosas interesantes que podemos hacer con él. Si entrecerramos los ojos lo suficiente en el triángulo, podemos ver triángulos invertidos como nodos de un gráfico fractal. ¡Vamos a orientarnos en ese gráfico!
Primero, asignemos un número a cada nodo. El triángulo invertido más grande será el nodo cero, y luego descenderemos capa por capa (ancho primero), asignando números consecutivos en el orden superior-izquierda-derecha:
Haga clic para obtener una versión más grande donde los números pequeños son un poco menos borrosos.
(Por supuesto, este patrón continúa ad infinitum dentro de los triángulos azules). Otra manera de definir la numeración es que el nodo central tiene el índice 0
, y los hijos del nodo i
(triángulos adyacentes de la próxima a menor escala) tienen índices 3i+1
, 3i+2
y 3i+3
.
¿Cómo nos movemos alrededor de este gráfico? Hay hasta seis pasos naturales que uno puede tomar desde cualquier triángulo dado:
- Siempre se puede mover a través del punto medio de uno de los bordes a uno de los tres hijos del nodo actual. Designaremos estos movimientos como
N
,SW
ySE
. Por ejemplo, si estamos actualmente en el nodo2
, éstos llevaría a nodos7
,8
,9
, respectivamente. Otros movimientos a través de los bordes (a descendientes indirectos) no están permitidos. - También se puede mover a través de una de las tres esquinas, siempre que no toque el borde del triángulo, ni al padre directo ni a uno de los dos antepasados indirectos. Designaremos estos movimientos como
S
,NE
yNW
. Por ejemplo, si actualmente estamos en el nodo31
,S
conduciría a10
,NE
sería inválido yNW
conduciría a0
.
El reto
Dados dos enteros no negativos x
y y
, encuentre el camino más corto de x
a y
, utilizando solo los seis movimientos descritos anteriormente. Si hay varias rutas más cortas, envíe cualquiera de ellas.
Tenga en cuenta que su código debería funcionar para algo más que los 5 niveles representados en el diagrama anterior. Puedes suponer eso x, y < 1743392200
. Esto garantiza que quepan dentro de un entero con signo de 32 bits. Tenga en cuenta que esto corresponde a 20 niveles del árbol.
Su código debe procesar cualquier entrada válida en menos de 5 segundos . Si bien esto descarta una búsqueda de amplitud de fuerza bruta, debería ser una restricción bastante flexible: mi implementación de referencia maneja la entrada arbitraria para la profundidad 1000 en medio segundo (eso es ~ números de 480 dígitos para los nodos).
Puede escribir un programa o función, tomando la entrada a través de STDIN (o la alternativa más cercana), argumento de línea de comando o argumento de función y generando el resultado a través de STDOUT (o la alternativa más cercana), el valor de retorno de la función o el parámetro de función (out).
El resultado debe ser una lista plana, sin ambigüedades de las cuerdas N
, S
, NE
, NW
, SE
, SW
, utilizando cualquier separador razonable (espacios, saltos de línea, comas, ","
...).
Aplican reglas estándar de código de golf .
Casos de prueba
Los primeros casos de prueba se pueden resolver a mano utilizando el diagrama anterior. Los otros aseguran que las respuestas sean lo suficientemente eficientes. Para aquellos, puede haber otras soluciones de la misma longitud que no se enumeran.
0 40 => N N N N
66 67 => S SW N N N
30 2 => NW NW -or- NE SW
93 2 => NE SW
120 61 => NW NW NW NW N SE SW N
1493682877 0 => S S NW NW
0 368460408 => SW SW N N SW SW SE SW SW N SE N N SW SW N SE SE
1371432130 1242824 => NW NW NE NW N SE SW SW SW SE SE SW N N N N SW
520174 1675046339 => NE NW NE NE SE SE SW SW N SE N SW N SW SE N N N N SE SE SW SW
312602548 940907702 => NE NW S SW N N SW SE SE SE SW SE N N SW SE SE SE SW
1238153746 1371016873 => NE NE NE SE N N SW N N SW N SE SE SW N SW N N SE N SE N
547211529 1386725128 => S S S NE NW N N SE N SW N SE SW SE SW N SE SE N SE SW SW N
1162261466 1743392199 => NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE
fuente
APL (Dyalog Unicode) ,
144132129118133132130124117 bytes SBCSMuchas gracias a Ven y ngn por su ayuda para jugar al golf en The APL Orchard , un excelente lugar para aprender el idioma APL.
⎕IO←0
. Sugerencias de golf bienvenidas.Editar: -12 bytes gracias a Ven y ngn cambiando la forma en que
n
se define y cambiando de indexación 1 a indexación 0. -3 debido a la corrección de un error donde no todo se cambió a 0-indexación. -11 bytes debido al cambio de cómoP
yQ
se definen. +15 bytes debido a la solución de un problema en el que mi algoritmo era incorrecto, gracias a ngn por ayudarme a calcular las[⊃⍋|M-s]
sección. -2 bytes de reorganizar el método de encontrar la ruta de retroceso y +1 byte para la corrección de errores. -2 bytes gracias a Adám por reorganizar la definición deI
. -6 bytes gracias a ngn por reorganizar la definición'S' 'NE' 'NW' 'N' 'SW' 'SE'
y por reorganizar cómot
se define (ya no es una variable separada). -7 bytes gracias a ngn de golf cómos
se define.Pruébalo en línea!
Una explicación del error en el algoritmo.
El problema básico es que pensé que el camino más corto fue directamente a través del antepasado común y, de hecho, no podía pasar por un antepasado del antepasado común. Esto es incorrecto como lo demostrarán los siguientes ejemplos.
De 66 a 5
Desde 299792458 hasta 45687
Explicación del código.
Solución alternativa usando Dyalog Extended y dfns
Si usamos
⎕CY 'dfns'
laadic
función, implementa nuestra numeración biyectiva base-n (que fue la inspiración para la versión que uso) para muchos menos bytes. Cambiar a Dyalog Extended también ahorra una gran cantidad de bytes y aquí estamos. Muchas gracias a Adám por su ayuda en el golf. Sugerencias de golf bienvenidas!Edición: -8 bytes debido a cambios en cómo
P
yQ
se definen. -14 bytes debido al cambio a Dyalog Extended. -2 debido al uso de un programa completo para eliminar los corchetes dfn{}
. +17 bytes debido a la solución de un problema en el que mi algoritmo era incorrecto, gracias a ngn por ayudarme a calcular las[⊃⍋|M-s]
sección. +1 byte a la corrección de errores. -2 bytes gracias a Adám por reorganizar la definiciónI
y -1 byte por recordar poner mis campos de golf en ambas soluciones. -3 bytes gracias a ngn reorganizando la generación de las direcciones cardinales, +1 byte al corregir un buggy de golf, y -3 bytes gracias a ngn reorganizando cómot
se define (ya no es una variable separada). -7 bytes gracias a ngn reorganizando cómos
se define.APL (Dyalog Extended) ,
12311510199116117114109102 bytesPruébalo en línea!
fuente