Dyalog APL, 27 caracteres
⊃⌽∨.∧⍨⍣≡1≥+/¨|∘.-⍨,(~×⍳∘⍴)⎕
⎕
entrada evaluada APL distingue entre una matriz y un vector de vectores. Este programa supone que la entrada es una matriz.
(~×⍳∘⍴)A
es un tenedor equivalente a (~A) × ⍳⍴A
. Es necesario evitar mencionar ⎕
dos veces o introducir una variable.
⍴A
es la forma de A
. Para una matriz de 4 por 7 la forma es 4 7
.
⍳
Es el generador de índice. ⍳4
es 1 2 3 4
. ⍳4 7
son los vectores (1 1)(1 2)...(4 7)
dispuestos en una matriz de 4 por 7.
~A
voltea los pedazos de A
.
×
Al multiplicar ⍳⍴A
por los bits invertidos, conservamos las coordenadas de todas las celdas libres y convertimos todas las paredes 0 0
.
,
deshilacha la matriz de pares de coordenadas, es decir, la linealiza en un vector. En este caso, el vector consistirá en pares.
∘.-⍨A
o A∘.-A
resta elementos de A
pairwise. Tenga en cuenta que aquí los elementos de A
sí mismos son pares.
|
valor absoluto
+/¨
suma cada par de valores absolutos. Esto nos da las distancias de la cuadrícula entre cada par de celdas en el laberinto, excepto para las paredes.
1≥
solo estamos interesados en vecinos a una distancia no mayor a 1, esto también excluye paredes. Ahora tenemos una matriz de adyacencia de un gráfico.
∨.∧⍨⍣≡
Floyd: algoritmo de cierre transitivo de Warshall
(f⍣n)A
(no se usa aquí) donde n
es un número entero es el operador de potencia. Se aplica f
a A
n
los tiempos: f f ... f A
.
(f⍣g)A
donde g
es una función, es el operador de punto fijo, también conocido como "límite de potencia". Se mantiene en el cálculo de la serie A
, f A
, f f A
, ... hasta ((f⍣i)A) g ((f⍣(i+1))A)
Devuelve verdadero para algunos i
. En este caso usamos match ( ≡
) como g
.
∨.∧⍨A
o A∨.∧A
es un paso en el algoritmo de Floyd. f.g
es una generalización de la multiplicación de matrices ( +.×
), aquí usamos conjunción ( ∧
) y disyunción ( ∨
) en lugar de +
y ×
.
⊃⌽
Después de ⍣≡
haber aplicado el paso suficientes veces y alcanzado un estado estable, debemos mirar hacia arriba en la esquina superior derecha de la matriz para obtener el resultado, así que lo volteamos ( ⌽
) y tomamos el primer elemento, arriba a la izquierda ( ⊃
).
Visualización de ⍣≡
los pasos de