Entrada:
Un laberinto que contiene los personajes:
--
(pared horizontal);|
(pared vertical);+
(conexión);(espacio para caminar);
I
(Entrada);U
(salida).
Es decir, una entrada podría verse así:
+--+--+--+--+--+--+--+--+--+--+
I | | |
+ +--+--+--+ + + + +--+ +
| | | | | |
+--+--+--+ +--+--+ + + +--+
| | | | |
+ +--+--+ + +--+--+ +--+ +
| | | | | |
+--+ + +--+--+ +--+--+ + +
| | | | | |
+ +--+--+--+ +--+--+ + + +
| | | | | |
+--+ + +--+--+ +--+--+--+--+
| | | | |
+ + +--+--+--+ +--+ + + +
| | | | | | | |
+--+--+ + +--+ + + +--+ +
| | | | | |
+ +--+--+--+ + + + + +--+
| | | | U
+--+--+--+--+--+--+--+--+--+--+
Salida:
El más eficiente ruta debe caminar para llegar desde la entrada hasta la salida del laberinto (a través del laberinto), indicado por los caracteres que indican la izquierda, derecha, arriba y abajo (es decir >
; <
; ^
; v
).
Reglas de desafío:
- Puede tomar la entrada en cualquier formato razonable. String-array, Single String con nuevas líneas, 2D char-array, etc., son todos los formatos de entrada posibles.
- La salida puede constar de cuatro caracteres distintos. Es decir
><^v
;→←↑↓
;⇒⇐⇑⇓
;RLUD
;0123
;ABCD
; etc.) - Se le permite agregar espacios o arrastrar nueva línea a la salida si lo prefiere; Esto es opcional.
- Los pasos se cuentan por cuadrado (ver cuatro
+
símbolos para los cuadrados), y no por carácter. - El laberinto puede tener un tamaño de 5x5 a 15x15, y siempre será un cuadrado (por lo que no habrá casos de prueba para laberintos de 5x10).
- Puede suponer que cada laberinto tiene una o más rutas válidas de principio a fin, y siempre genera el más corto (consulte los casos de prueba 4 y 5).
- Si hay varias rutas con la misma longitud, puede elegir cuál generar (consulte el caso de prueba 6).
- No puede "caminar" fuera de los límites del laberinto (vea los casos de prueba 7 y 8).
Reglas generales:
- Este es el código de golf , por lo que la respuesta más corta en bytes gana.
No permita que los lenguajes de code-golf lo desanimen a publicar respuestas con lenguajes que no sean codegolf. Trate de encontrar una respuesta lo más breve posible para 'cualquier' lenguaje de programación. - Se aplican reglas estándar para su respuesta, por lo que puede usar STDIN / STDOUT, funciones / método con los parámetros adecuados, programas completos. Tu llamada.
- Las lagunas predeterminadas están prohibidas.
- Si es posible, agregue un enlace con una prueba para su código.
- Además, agregue una explicación si es necesario.
Casos de prueba:
1. Input:
+--+--+--+--+--+--+--+--+--+--+
I | | |
+ +--+--+--+ + + + +--+ +
| | | | | |
+--+--+--+ +--+--+ + + +--+
| | | | |
+ +--+--+ + +--+--+ +--+ +
| | | | | |
+--+ + +--+--+ +--+--+ + +
| | | | | |
+ +--+--+--+ +--+--+ + + +
| | | | | |
+--+ + +--+--+ +--+--+--+--+
| | | | |
+ + +--+--+--+ +--+ + + +
| | | | | | | |
+--+--+ + +--+ + + +--+ +
| | | | | |
+ +--+--+--+ + + + + +--+
| | | | U
+--+--+--+--+--+--+--+--+--+--+
1. Output:
>v>>>vv<v>>v>v>>vvv>>>
2. Input:
+--+--+--+--+--+
I | | |
+ +--+--+ + +
| | | |
+ +--+ + + +
| | | | |
+ + +--+ + +
| | |
+--+ + +--+--+
| | U
+--+--+--+--+--+
2. Output:
>vvv>>v>>>
3. Input:
+--+--+--+--+--+
U | |
+ + +--+--+ +
| | | |
+--+--+ + +--+
| | |
+ +--+--+--+ +
| | | |
+ + + + +--+
| | I
+--+--+--+--+--+
3. Output:
<<<^<v<^^>>^<^<<
4. Input (test case with two valid paths):
+--+--+--+--+--+
U | |
+ + +--+--+ +
| | |
+--+--+ + +--+
| | |
+ +--+--+--+ +
| | | |
+ + + + +--+
| | I
+--+--+--+--+--+
4. Output:
<<^>^<^<<^<< (<<<^<v<^^>>^<^<< is less efficient, and therefore not a valid output)
5. Input (test case with two valid paths):
I
+--+--+--+--+--+--+--+--+--+--+ +--+--+--+--+
| | | | |
+ + + +--+--+--+ + +--+--+ +--+--+ + +
| | | | | | | |
+--+--+--+ +--+ + +--+--+--+--+ +--+--+--+
| | | | | | | | |
+ + + + + +--+ + + + +--+--+ +--+ +
| | | | | | | |
+ +--+--+--+ +--+--+ + +--+ +--+--+ +--+
| | | | | | | | |
+ +--+ + +--+ +--+--+ +--+--+ + +--+ +
| | | | | | |
+ + +--+--+--+--+ + +--+--+--+ +--+ +--+
| | | | | | | |
+--+--+--+ + +--+--+ +--+ + +--+ +--+ +
| | | | | | | |
+ +--+--+--+--+ + + +--+--+--+ + + + +
| | | | | | | | | |
+--+ + + + + + +--+--+ + + +--+ + +
| | | | | | | | | |
+--+ +--+--+ + + + +--+--+--+ + + + +
| | | | | | | | | |
+ +--+ +--+--+ + +--+--+ + +--+ + + +
| | | | | | | | | |
+--+--+--+ + + +--+ + +--+--+ +--+ + +
| | | | | | | |
+ + +--+--+--+--+ +--+--+ +--+--+ +--+ +
| | | | | |
+ + + +--+--+--+--+--+--+--+--+ +--+ +--+
| | | |
+--+--+--+--+--+--+--+--+--+ +--+--+--+--+--+
U
5. Output:
v<<<v<vv<<v<v>>^>>^^>vvv>>>v>vv<vv<<v<v<^<^^^^<vvvvv<^<v<<v>v>>>>>>>v (v<<<v<vv<<v<v>>^>>^^>vvv>>>v>vv<vv<<v<v<^<^^^^<vvvvv>v>>>^>>^>^^>vvv<v<v<<v is less efficient, and therefore not a valid output)
6. Input:
+--+--+--+--+--+
I |
+ + + + + +
| |
+ + + + + +
| |
+ + + + + +
| |
+ + + + + +
| U
+--+--+--+--+--+
6. Output:
>>v>v>v>v> or >v>v>v>v>> or >>>>>vvvv> or etc. (all are equally efficient, so all 10-length outputs are valid)
7. Input:
I U
+ + +--+--+--+
| | | |
+ +--+--+ + +
| | | |
+--+ + +--+ +
| | | |
+ +--+ + + +
| | |
+--+ +--+--+ +
| | |
+--+--+--+--+--+
7. Output:
vv>v>^>^<<^
8. Input:
+--+--+--+--+--+
| | |
+ +--+ +--+ +
I | | | |
+ + +--+ + +
U | | | |
+--+--+ + + +
| | | |
+ +--+--+--+ +
|
+--+--+--+--+--+
8. Output:
>v<
Laberintos generados con esta herramienta (y en algunos casos ligeramente modificados).
code-golf
path-finding
maze
Kevin Cruijssen
fuente
fuente
v<<<<<<^^^^^
(siempre piensa fuera de la caja)>v>>>vv<v>>v>v>>vvv>>>
.Respuestas:
Retina ,
338281275273261 bytesPruébalo en línea!
Notas
0x20
) se reemplazan con interpunct (·
) tanto en esta respuesta como en el enlace TIO. El programa funciona bien si se restauran los espacios.AvKr
para arriba, abajo, izquierda y derecha, respectivamente. Esos pueden ser reemplazados con cualquier letra exceptoI
.Toma alrededor de 40 años en TIO para el caso de prueba 15 × 15. Se paciente.Se rediseñó la parte para encontrar el camino más corto una vez que el camino llegó a la salida. Resulta que eso estaba tomando mucho tiempo.Explicación
El programa consta de 3 fases:
Formato
Dado que el formato original del laberinto es bastante difícil de manejar, la primera parte del programa lo convierte a un formato diferente.
Células
En el formato original, cada celda se representa como una región 2 × 3:
Dado que la columna derecha no contiene información, el programa identifica las celdas como cualquier región 2 × 2 con un
+
en la esquina superior izquierda.Esto nos deja con 3 tipos de células:
U
en el caso de prueba 1 está en una R-Cell.En el nuevo formato, las celdas se representan como una cadena de longitud variable:
La pared izquierda y superior se copian del formato original. El número de columna se basa en la posición horizontal de la celda y se utiliza para la alineación (identificando celdas directamente una encima de la otra o debajo de la otra). La ruta es una cadena alfabética utilizada durante la fase de relleno para guardar la ruta más corta para llegar a esa celda. La ruta y el marcador de salida se explicarán más adelante
Medias celdas
Aunque la mayoría del laberinto son células, hay regiones del laberinto que no son células:
+
s a lo largo de la pared derecha no forman celdas, ya que están en la última columna.+
a la izquierda de ellas. Por ejemplo, la entradaI
en el caso de prueba 1 está en una L Media Celda.Técnicamente, hay medias celdas T sobre el laberinto (cuando hay relleno superior) y medias celdas B (a lo largo de la pared inferior cuando no hay relleno inferior) pero no están representadas en el nuevo formato.
La fila superior de una media celda se eliminaría como parte de la construcción de celdas completas en la misma fila, por lo que las medias celdas se representan en el nuevo formato como
Un R Half-cell es justo
|
. Un L Half-cell tiene soloI
el camino, solo el marcador de salida y un camino vacío, o simplemente una pared vacía.Entradas y salidas.
Si la entrada está a la izquierda, a la derecha o al fondo del laberinto, entonces el marcador de entrada se
I
incluiría naturalmente en la (media) celda como el camino, que se puede eliminar al regresar el camino final.Si la entrada está por encima del laberinto, se toma el primer paso (hacia abajo) durante la fase de construcción, ya que las semicélulas T se eliminan durante la construcción. Esto mantiene una ruta viable en una celda llena. La pared superior se cierra después.
Si la salida está a la izquierda, a la derecha o al fondo del laberinto, entonces
U
naturalmente se incluiría en la (media) celda. Para evitar ser confundido con una ruta,&
se usa el marcador de salida no alfanumérico en lugar deU
. El marcador de salida está incrustado en una celda o media celda (como se especificó anteriormente).Si la salida está por encima del laberinto, entonces sería el único agujero que puede pasar por encima de la fila superior de celdas (ya que el de la entrada, si está presente, ya estaría cerrado). Cualquier camino que llegue a ese agujero puede salir del laberinto dando un paso hacia arriba.
Por último, cualquier celda B que contenga la entrada o la salida debe cerrar su pared izquierda para evitar "resolver" el laberinto caminando por las celdas B. Las entradas y salidas en celdas R o medias celdas L no necesitan más procesamiento ya que el algoritmo de relleno de inundación no permite movimientos verticales hacia / desde ellas.
Ejemplo
Como ejemplo, el primer caso de prueba
es
en el nuevo formato. Puedes convertir otros laberintos aquí .
Fase de construcción
La fase de construcción conforma las primeras 13 líneas del programa.
Convierte la salida en L Media celda para salir del marcador
Agrega paredes a la izquierda de la entrada y sale en las celdas B
Da el primer paso si la entrada está por encima del laberinto
Realiza la conversión real
Cierra el orificio de entrada superior
Mantiene solo líneas con a
1
. Dado que los laberintos tienen al menos 5 celdas de ancho y los números de columna se producen en incrementos de 3, una línea con celdas de nuevo formato debe contener un número de columna entre 10 y 19.Convierte la salida en la celda R o la celda B para salir del marcador
Fase de llenado
La fase de llenado conforma las siguientes 8 líneas del programa. Utiliza un algoritmo de relleno de inundación para llenar todas las celdas con el camino más corto para llegar allí desde la entrada.
Pone toda la fase de llenado en un bucle para llenar todo el laberinto.
Cada celda capaz de moverse hacia la izquierda lo hace. Una celda puede moverse a la izquierda si
Entonces, cada celda capaz de moverse hacia la derecha lo hace. Una celda puede moverse hacia la derecha si
Entonces, cada celda capaz de moverse hacia abajo lo hace. Una celda puede moverse hacia abajo si
Tenga en cuenta que las medias celdas L no pueden moverse hacia abajo ya que no tienen números de columna.
Entonces, cada celda capaz de moverse hacia arriba lo hace. Una celda puede moverse hacia arriba si
Fase de retorno
La fase de retorno constituye las últimas 5 líneas del programa. Esta fase busca y devuelve la ruta rellenada en la celda de salida.
El patrón de la ruta en la salida depende de dónde está la salida:
& <path>
<left wall> <column number> & <path>
<left wall> <column number> · <path>
y en la fila superior.Encuentra una celda en la línea superior con una pared superior vacía y una ruta no vacía. Esto se encarga del último caso agregando el último paso y el marcador de salida.
Coincide y devuelve una ruta no vacía después de un marcador de salida.
Elimina el marcador de salida y el
I
prefijo de la ruta.fuente
AvKr
? ¿Tienen un significado / son abreviaturas para arriba, abajo, izquierda y derecha en su idioma nativo, o hay alguna otra razón por la que ha elegido esos caracteres específicos?AvKr
son lo más parecido a las flechas en alfanumérico.Perl 6 ,
259295 bytesCómo funciona
Esto exprime el laberinto para que el interior de cada celda sea 1x1 en lugar de 2x1 caracteres de espacio:
Esta es la función recursiva de búsqueda de rutas. Toma tres parámetros: la coordenada actual
c=(y,x)
, la lista de coordenadas ya visitadasv
y la rutap
tomada hasta ahora (como una lista de caracteres de flecha).Si el carácter en la coordenada actual es un espacio, recurre a sus cuatro vecinos.
Si el carácter en la coordenada actual es a
I
, recurre a los dos vecinos que no están "a lo largo del borde", para obligar a las soluciones a atravesar el laberinto y no a su alrededor.Si el carácter en la coordenada actual es a
U
, llamatake
a la cadena de ruta acumulada.La función recursiva se llama inicialmente con la coordenada de la letra
I
, que se encuentra usando una expresión regular.La
gather
palabra clave recopila todos los valores en los quetake
se llamó dentro de la función, es decir, todas las rutas no cíclicas válidas a través del laberinto.Se elige el camino más corto, cada segunda flecha se suelta para tener en cuenta el hecho de que se requieren dos movimientos idénticos para pasar de una celda a la siguiente, y las flechas restantes se concatenan para formar la cadena que se devuelve desde el lambda.
fuente
Python 2: 302 bytes
Toma la entrada como una matriz de cadenas, todas con la misma longitud. Imprime
0
para derecha,1
para abajo,2
para izquierda y3
para arriba.Explicación
Tomé un enfoque diferente al de las otras respuestas. Idea general: busque de forma recursiva encontrando el camino más corto entre avanzar y rotar el tablero 90 grados.
Pruébalo en línea!
fuente
I
para evitar que el camino salga del laberinto. Disfruta tu estadía y +1 de mi parte. :)JavaScript (ES6), 356 bytes
Toma la entrada como una matriz 2D de caracteres. Cada línea debe ir rellenada a la izquierda por un espacio y no tener espacio final, sin importar dónde se encuentren los puntos de inicio / finalización.
Utiliza la idea de smls de aplastar el laberinto para hacer que cada celda sea 1x1 y eliminar las flechas repetidas de la salida.
No golfista y explicado
Fragmento de prueba
Mostrar fragmento de código
fuente
Retina , 416 bytes
Pruébalo en línea! Si hubiera visto esta pregunta cuando se publicó originalmente, esta es probablemente la respuesta que habría dado, así que la estoy publicando de todos modos, a pesar de que hay una respuesta mucho mejor en Retina. Explicación:
Completa el borde. Esto evita caminar alrededor del exterior del laberinto (por ejemplo, para el caso de prueba 7).
Coloque un marcador no alfabético en la entrada.
Las inundaciones se llenan desde la salida hasta la entrada. En cada paso, use una letra para indicar la mejor dirección a seguir (wasd; esto podría ser familiar para los jugadores; también había considerado hjkl pero me pareció demasiado confuso). Además, prefiere repetir la misma dirección; Esto evita ir hacia la izquierda / derecha entre dos celdas adyacentes verticalmente.
Suponga que el primer paso está abajo.
Pero si hay una letra arriba, izquierda o derecha de la entrada, cámbiela al primer paso.
Mueva el marcador en la dirección del último movimiento, leyendo la dirección del siguiente movimiento desde el cuadrado al que se mueve el marcador, y agréguelo a la lista de direcciones. Esto se repite hasta que
U
se alcanza.Elimine todo después de las instrucciones ya que ya no es necesario.
La cuadrícula original está en un diseño de 3 × 2. Mientras nos movemos verticalmente si zigzagueamos horizontalmente, el relleno de inundación optimizará el movimiento y solo moverá 3n-1 caracteres horizontalmente, por lo que al dividir entre tres, debemos redondear. Verticalmente solo dividimos por 2.
También investigé una verdadera solución de cuadrícula cuadrada, es decir, donde la matriz de caracteres es cuadrada en lugar de ser un diseño de 3 × 2 con un borde opcional. Aunque probablemente no sea conforme a la pregunta, la capacidad de transposición redujo el recuento de bytes a 350: ¡ Pruébelo en línea!
fuente
-
alrededor de los caracteres de entrada y salida. Dado que el desafío se trata principalmente de atravesar el laberinto, supongo que está bien, pero tengo curiosidad: ¿cuáles fueron los problemas cuando no había colocado esas paredes encima / debajo delI
yU
? Además, ¿podría verificar que esto funciona para el caso de prueba 7 conI
yU
en la parte superior en lugar de los lados? TIO excede el límite de 60 segundos, por lo que no puedo probarlo yo mismo. Aunque lea su explicación de intentar primero bajar por defecto, supongo que debería funcionar bien.