Os presento con orgullo ...
<}74}}:23}29}59}}}}}}}:111_}}}}:::::::23_}:111
? @
:" }}_47}_95 3""""""""(
_ : } _ } {=}
2 23_}29_ _ ; : \
0 ; 3 +_( 3_" 60{ .{.{.
"-_95:}}"" 2 0 ) 2 " _ _ {
"" _ : 2 _ ."(; } 3 .{
;_92}_47} : _ 0 = : * ;
: "" 2 {.{{ . -""(
}}:59_}}:::: "";_ . { _ "
} " {.{.{. 32.
}}}_95:}}}}_20-
... mi nuevo laberinto bidimensional esolang! El código anterior no es increíblemente bueno (hay 161 espacios y 25 NOP, por lo que un mejor diseño podría acortar mucho esto), pero al menos logré demostrar que el lenguaje es utilizable para tareas no triviales. :)
Cómo funciona
Primero, una descripción rápida del idioma:
- Labyrinth opera en dos pilas, principal y auxiliar , que pueden contener enteros con signo arbitrario. En la parte inferior de ambas pilas hay una cantidad infinita de ceros.
- Los comandos son caracteres individuales en una cuadrícula 2D y forman un laberinto (es decir, los caracteres desconocidos, particularmente los espacios, son paredes).
"
es un NOP que no es un muro y puede ser útil para rellenar ciertas rutas en el código. A diferencia de muchos otros lenguajes 2D, los bordes no se ajustan.
- El puntero de instrucción (IP) comienza en el primer carácter no mural (en orden de lectura) que se mueve hacia la derecha.
@
termina el programa
- Si es posible, la IP sigue los corredores (también alrededor de las curvas). Si la IP tiene varias celdas a las que moverse, generalmente girará a la izquierda si la parte superior de la pila principal es negativa, avanzará si es cero o girará a la derecha si es positiva. Cuando el IP golpea una pared, invierte la dirección. (Hay algunas sutilezas más, pero no deberían importar este código). Esta es la única forma de implementar el flujo de control.
- Además de los comandos de manipulación aritmética y de pila, el código fuente puede modificarse en tiempo de ejecución con los cuatro comandos
>v<^
que desplazarán una fila o columna del código fuente cíclicamente por una celda. La fila o columna afectada depende de la parte superior de la pila. Si la propia fila o columna de la IP se desplaza, se moverá con el cambio. Esto hace posible saltar de un borde del código fuente al otro.
Ahora para este desafío particular, aquí está la idea general del algoritmo:
- Empuje los extremos de los automóviles hasta los capó (es decir
/ \_o oo o
) en la pila auxiliar.
- Lea la entrada y determine si presionar
__
o el /\
siguiente.
- Empuje el resto de los automóviles (es decir,
__ __ _/ \
y dos espacios principales) en la pila auxiliar.
- Sujetar la entrada a un valor máximo de
20
, Llamemos a esto N .
- Ahora haga lo siguiente 3 veces:
- Imprimir N espacios.
- Imprime 6 caracteres almacenados.
- Imprimir 60 - 3 * N espacios.
- Imprime 6 caracteres almacenados.
- Imprime una nueva línea.
Finalmente, veamos algunas partes del código. La IP comienza en la esquina superior izquierda, en un comando de cambio de cuadrícula. La parte superior de la pila principal es 0
(que se usa como índice relativo), por lo que la primera fila se desplaza hacia la izquierda, lo que también mueve la IP al extremo derecho de la cuadrícula. Ahora la primera fila simplemente se ejecuta de derecha a izquierda, lo que empuja el primer conjunto de caracteres fijos a la pila auxiliar:
}74}}:23}29}59}}}}}}}:111_}}}}:::::::23_}:111<
Este cambio de fila es útil para jugar al golf cuando desea comenzar con una gran cantidad de código lineal.
A continuación, leemos la entrada y empujamos los sombreros correctos:
?
:"
_
2
0 ;
"-_95:}}""
"" _
;_92}_47}
El bit de la izquierda con los tres NOP envía resultados negativos a lo largo de la rama superior y resultados no negativos a lo largo de la rama inferior. A la derecha se vuelven a unir.
Ahora sigue otra sección lineal grande (que probablemente podría jugar mucho con otro truco de cambio de fila):
}}_47}_95
: }
23_}29_ _
3
2
:
:
:
}}:59_}}::::
}
}}}_95:}}}}
Esto empuja el resto de los autos a la pila auxiliar.
A continuación, calculamos min(20, input)
, que es similar a la primera rama:
;
+_(
0 )
2 _
_ 0
"" 2
"";_
"
_20-
Finalmente, tenemos el bucle que se ejecuta tres veces para imprimir las líneas. Cada iteración del bucle contiene dos bucles pequeños (3x3) para imprimir los espacios, así como dos secciones para imprimir 6 caracteres desde la pila auxiliar:
@
3""""""""(
_ } {=}
: \
3_" 60{ .{.{.
2 " _ _ {
."(; } 3 .{
= : * ;
{.{{ . -""(
. { _ "
{.{.{. 32.
Un ingenioso truco al que me gustaría llamar la atención es .{.{.
en el borde derecho. Este es un callejón sin salida, por lo que, aparte del .
final, el código se ejecuta dos veces, una hacia adelante y otra hacia atrás. Esto proporciona una forma ordenada de acortar el código palindrómico (el problema es que debe asegurarse de que la IP tome el giro correcto cuando salga del callejón sin salida nuevamente).
/ \
en lugar de abajo_ _
?