Prólogo, 284 bytes
e(S,[0|X]):-e(S,X).
e([A|S],[A|X]):-S=X;e(S,X).
v(X/Y,76,Y/Z):-Z is -X.
v(X/Y,82,Z/X):-Z is -Y.
v(D,0,D).
c([],0/0-0/1,[0/0]).
c([H|T],K/L-D/E,[K/L|C]):-c(T,I/J-X/Y,C),v(X/Y,H,D/E),K is I+X,L is J+Y,\+member(K/L,C).
n(X):-X=0;n(Y),X#=Y+1.
p(S,L):-n(L),length(X,L),e([0|S],X),c(X,_,_).
Esta es una declaración bastante directa del algoritmo y bastante ineficiente (no todos los casos de prueba se ejecutaron en un tiempo razonable, aunque la mayoría lo hizo). Funciona mediante la generación de todas las longitudes posibles para la salida de 1 hacia arriba ( n
); generar todas las secuencias posibles de izquierda / adelante / derecha de esa longitud que sean consistentes con la entrada (implementado en e
; se llama a la nueva ruta X
); luego verificando la primera ruta de ese tipo que sea válida ( c
que llama v
para manejar los efectos de los giros izquierdo y derecho en los deltas x e y). La longitud de retorno es la primera salida vista enL
. (Penalización de +2 si desea evitar que la función devuelva otras salidas posibles para la longitud si retrocede en ella; nunca está claro cómo se debe contar la función idiosincrásica de Prolog).
Aquí no hay muchos trucos de golf, pero hay algunos. n
se implementó con un solucionador de restricciones porque permite eliminar más espacios en blanco sin confundir el analizador; esto podría requerir el uso de GNU Prolog, no estoy seguro de eso. (No podría hacer lo mismo c
ya que necesita manejar números negativos). La implementación de e
es considerablemente menos eficiente de lo que debe ser, al hacer coincidir una lista de múltiples maneras; el más eficiente e([],[]).
sería seis bytes más largo (permitiría S=X;
eliminar la línea 2, pero eso es solo una ganancia de cuatro en comparación con una pérdida de diez). Para permitirme X/Y
unir las coordenadas y las direcciones como un todo, o solo como parte, las represento como (es decir, un AST no evaluado, que se puede combinar), lo que me permite utilizar la notación infija.
Prolog, 256 bytes, demasiado ineficiente para probar fácilmente
Por supuesto, como se trata de Prolog, muchas de las funciones son reversibles, por ejemplo, c
se pueden utilizar para generar todas las rutas desde el origen hasta un par de coordenadas en particular. Además, c
naturalmente genera desde el más corto al más largo. Esto significa que, en lugar de pedir explícitamente una longitud mínima, podemos c
generar todos los caminos que van a cualquier parte y luego buscar el primero que sea coherente con la entrada:
e(S,[0|X]):-e(S,X).
e([A|S],[A|X]):-S=X;e(S,X).
v(X/Y,76,Y/Z):-Z is -X.
v(X/Y,82,Z/X):-Z is -Y.
v(D,0,D).
c([],0/0-0/1,[0/0]).
c([H|T],K/L-D/E,[K/L|C]):-c(T,I/J-X/Y,C),v(X/Y,H,D/E),K is I+X,L is J+Y,\+member(K/L,C).
p(S,L):-c(X,_,_),length(X,L),e([0|S],X).
Esto tiene un rendimiento exponencial (O (3 n ), donde n es la salida). Sin embargo, logré verificarlo en algunas de las pruebas más pequeñas (toma alrededor de 7 segundos para la salida 14 y alrededor de 20 para la salida 15, en mi computadora).