Befunge, 344 bytes
&v>>>#p_:63p:43g`\!+v>/*53g+\01g:2%2*1-\2/!*63g+\0\:v
40$ v++!\`g14:p35:\<^2\-1*2%2p10::%4+g00:\g36\g35-1_v
#11^$_83p73v >1+:41g`!#v_$,1+:43g`!#v_@>->2>+00p+141^_
<p1^ vp< ^,g+7g36:<<<<1+55p36:<<<< ^1?0^#7g36g35*
8&p|!++!%9#2g+7g10\*!-g38g10!-g37:g00!!*<>3^
443>:!#v_>>1-::3%1-:53g+00p\3/1-:63g+01p^
^>^>>$#<"#"53g63g7+p41g53g-43g63g-+!#^_
Pruébalo en línea!
Como @flawr mencionó en su respuesta de MATLAB, esto puede llevar algún tiempo si el tamaño del campo no es trivial. De hecho, es bastante fácil entrar en una situación en la que realmente no vale la pena intentar esperar a que termine, porque es muy probable que espere hasta el final de los tiempos.
Para entender por qué sucede esto, es útil ver el programa mientras se ejecuta en uno de los muchos "depuradores visuales" de Befunge. Dado que los datos y el código son lo mismo en Befunge, podrá ver la ruta a medida que cambia con el tiempo. Por ejemplo, aquí hay una breve animación que muestra cómo se vería una parte de una carrera en una ruta lenta.
Una vez que el algoritmo decide hacer ese giro fatídico a la izquierda en la parte inferior del límite del campo, esencialmente se ha condenado a una vida de vagar sin rumbo. A partir de ese momento, debe seguir todos los caminos posibles en esa área cercada antes de que pueda retroceder e intentar girar a la derecha. Y la cantidad de caminos potenciales en estos casos puede convertirse fácilmente en astronómica.
En pocas palabras: si parece que lleva mucho tiempo, probablemente sea una buena idea abortar la ejecución y comenzar de nuevo.
Explicación
Esto es básicamente un algoritmo recursivo, que prueba todas las rutas posibles a través del campo y luego desenrolla los pasos que ya se han seguido cada vez que se atasca. Como Befunge no tiene el concepto de funciones, una función recursiva está fuera de discusión, pero podemos emular el proceso rastreando el estado en la pila.
Esto funciona al llenar la pila con coordenadas potenciales que podemos querer seguir. Luego sacamos un conjunto de la pila y verificamos si es adecuado (es decir, dentro del rango y no superpuesto con una ruta existente). Una vez que tenemos un buen lugar, escribimos un#
en el campo de juego en esa ubicación y agregamos esos detalles a la pila en caso de que necesitemos retroceder más tarde.
Luego empujamos cuatro conjuntos de coordenadas adicionales en la pila (en orden aleatorio) que indican los posibles caminos que podemos tomar desde esta nueva ubicación, y saltamos de regreso al inicio del ciclo. Si ninguna de las rutas potenciales es factible, llegaremos al punto en la pila donde guardamos la ubicación de#
que escribimos, por lo que desharemos ese paso y continuaremos probando las coordenadas potenciales de un paso anterior.
Así es como se ve el código con las diversas partes componentes resaltadas:
Lea el ancho y la altura del campo, y presione las coordenadas de inicio junto con un 0
marcador de tipo para indicar una ruta potencial en lugar de una ubicación de retroceso.
Verifique las ubicaciones de retroceso (indicadas por un 1
marcador de tipo) que se revierten con un p
comando simple , ya que se almacenan en el formato exacto necesario para volver a escribir un espacio en el campo de juego.
Comprueba si las coordenadas todavía están dentro del campo de juego. Si están fuera de alcance, suéltelos de la pila y vuelva a intentarlo para probar las siguientes coordenadas potenciales.
Si están dentro del rango, obtenga los siguientes dos valores de la pila, que es la ubicación del paso anterior (requerido en la prueba que sigue a esto).
Compruebe si las coordenadas van a entrar en contacto con un segmento existente de la ruta. La ubicación del paso anterior obviamente se ignora de esta verificación.
Si todas las pruebas son exitosas, escriba unEmpuje cuatro destinos potenciales a los que se puede llegar desde la ubicación actual. El número aleatorio determina el orden en que se empujan y, por lo tanto, el orden en que se seguirán.#
en el campo de juego y verifica si hemos llegado a la ubicación de destino.
Si es así, escriba la ruta final y salga.
De lo contrario, guarde las coordenadas en la pila con un 1
marcador de tipo para retroceder más tarde.
Esto se interrumpe con un cálculo de número aleatorio que vamos a necesitar pronto. Regrese al inicio del bucle principal y procese los siguientes valores en la pila.