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