1{?)=}&~".>")!@(</=+={"/>}*
Desplegado:
1 { ? )
= } & ~ "
. > " ) ! @
( < / = + = {
" / > } * .
. . . . .
. . . .
Pruébalo en línea!
Explicación
Consideremos la secuencia b(a) = a(n) - 1
y reorganicemos un poco:
b(a) = a(n) - 1
= a(n-1)*(a(n-1)-1) + 1 - 1
= (b(n-1) + 1)*(b(n-1) + 1 - 1)
= (b(n-1) + 1)*b(n-1)
= b(n-1)^2 + b(n-1)
Esta secuencia es muy similar, pero podemos diferir el incremento hasta el final, lo que sucede al guardar un byte en este programa.
Así que aquí está el código fuente anotado:
Creado con el HexagonyColorer de Timwi .
Y aquí hay un diagrama de memoria (el triángulo rojo muestra la posición y orientación iniciales del puntero de memoria):
Creado con Timwi de EsotericIDE .
El código comienza en la ruta gris que envuelve la esquina izquierda, por lo que el bit lineal inicial es el siguiente:
1{?)(
1 Set edge b(1) to 1.
{ Move MP to edge N.
? Read input into edge N.
)( Increment, decrement (no-op).
Luego, el código golpea el <
cual es una rama e indica el inicio (y el final) del bucle principal. Mientras el borde N tenga un valor positivo, se ejecutará la ruta verde. Ese camino se ajusta alrededor de la cuadrícula varias veces, pero en realidad es completamente lineal:
""~&}=.*}=+={....(
No .
hay operaciones, por lo que el código real es:
""~&}=*}=+={(
"" Move the MP to edge "copy".
~ Negate. This is to ensure that the value is negative so that &...
& ...copies the left-hand neighbour, i.e. b(i).
}= Move the MP to edge b(i)^2 and turn it around.
* Multiply the two copies of b(i) to compute b(i)^2.
}= Move the MP back to edge b(i) and turn it around.
+ Add the values in edges "copy" and b(i)^2 to compute
b(i) + b(i)^2 = b(i+1).
={ Turn the memory pointer around and move to edge N.
( Decrement.
Una vez que esta disminución se reduce N
a 0
, se ejecuta la ruta roja:
")!@
" Move MP back to edge b(i) (which now holds b(N)).
) Increment to get a(N).
! Print as integer.
@ Terminate the program.