`:_64/"32}
,` (3 :=-{
"`{"; _v2$ ;`3
"`".:@ ; ".5(`3.
< "" `^`;>
Otra colaboración con @ MartinBüttner y en el lado más loco del espectro Labyrinth: por primera vez, tenemos los cuatro ^>v<
en un solo programa. Pruébalo en línea!
Explicación
El algoritmo general, que se ejecuta en un bucle, es el siguiente:
1. Read a char
2. If EOF:
3. Move all digits from auxiliary stack to main
4. Output all digits on main stack
5. Halt
Otherwise:
6. If char is a letter (c >= 64):
7. If random turns left:
8. Output char XOR 32
Otherwise:
9. Output char
Otherwise:
10. Shift char to auxiliary stack
11. If char is space (c-32 == 0):
12. Pull char back from auxiliary stack
13. Output underscore
Otherwise:
14. Continue loop
Para mantener la explicación compacta, aquí es más o menos cómo cada parte del programa corresponde al pseudocódigo anterior:
Aquí están las partes interesantes.
Obteniendo aleatoriedad en el laberinto
Solo hay una forma de obtener aleatoriedad en Labyrinth, y es cuando la IP intenta avanzar pero 1) no hay un camino hacia adelante ni hacia atrás y 2) hay caminos disponibles a izquierda y derecha. En este caso, la IP elige aleatoriamente entre las rutas izquierda y derecha.
Esto solo es posible utilizando los ^>v<
operadores, que muestran n
y desplazan la fila / columna n
en 1. Por ejemplo, el programa (¡ Pruébelo en línea! )
" 1
""v!@
2
!@
genera 1 o 2 al azar, ya que v
desplaza la columna con el desplazamiento 0 (es decir, la columna en la que está la IP) en 1, produciendo
"
""1!@
v
2!@
La IP está orientada hacia la derecha e intenta avanzar (la parte superior de la pila es cero) pero no puede. Tampoco puede moverse hacia atrás, por lo que elige aleatoriamente entre izquierda o derecha.
Trucos de golf
El programa comienza desde el primer carácter en el orden de lectura, que notará que en realidad es el paso 6. Sin embargo, al saltar de una pila de Labyrinth vacía se obtiene 0, por lo que se producen los pasos 10 y 14, cambiando un cero a la pila auxiliar, que es efectivamente un no-op.
La pila principal está efectivamente vacía después de cada iteración, lo que nos permite jugar al diseño del código usando >
y <
en los ceros implícitos en la parte inferior. La >
envuelve la fila inferior alrededor de modo que los movimientos IP desde la parte inferior derecha a la parte inferior izquierda, y los <
cambios de la fila de atrás. La IP luego felizmente se mueve hacia arriba en la columna izquierda para continuar el ciclo.
Los dígitos en Labyrinth explotan n
y empujan 10*n + <digit>
. Además, los caracteres se toman en el módulo 256 antes de salir. Poniendo estos dos juntos nos permite la salida 95 (subrayado) haciendo `33
al 32 (espacio), que funciona porque -3233 % 256 = 95
. Aunque hay otras formas de convertir 32 en 95 ( ;95
siendo la más fácil), trabajar con un número negativo aquí nos permite compactar un poco el código con giros a la izquierda.