@0@6000000@5
}0&0&0&0&0
>0@6&3
\\--\/&2
@0/\@4\/&1!!
@4@1..@2@5@3
IIIIIIIIIIII
FF&1FF&2FF&3
@1OO@2OO@3OO
:I
}1..}10001F7
=9&1++..&1&0
&0}0&1&0{1{1
{>\/{0//
:O
}0
+Z
+C
{0
Funciona solo para valores inferiores a 256 ya que Marbelous es un lenguaje de 8 bits.
Cómo funciona
Marbelous es un lenguaje 2D con valores representados por canicas de 8 bits que caen una celda en cada tic a menos que algún dispositivo evite que se caigan. Este programa maravilloso consta de 3 tableros; Comencemos con el más fácil:
:O
}0
+Z
+C
{0
:Oes el nombre de la placa (para ser precisos, O es el nombre y: le dice al interpretado que esta línea es un nombre. Al dar un nombre a las placas, otras placas pueden invocarlas como
}0un dispositivo de entrada, esto puede verse como un argumento de esta función. Esta celda será reemplazada por una canica de entrada (valor) cuando se llama a la función.
+ZAgrega 35 a cualquier canica que la pase y la deje caer. +CHace lo mismo pero solo agrega 12. {0Es una celda de salida , cuando una canica llega a esta celda, la función saldrá y devolverá el valor en este dispositivo de salida.
Entonces, todos juntos, este tablero toma un valor y luego le agrega 47. Para nosotros, esto significa que convierte cualquier número de un solo dígito en el código ASCII del dígito -1 (esto, por supuesto, también funcionará para 10).
:I
}1 .. }1 00 01 F7
=9 &1 ++ .. &1 &0
&0 }0 &1 &0 {1 {1
{> \/ {0 //
Este tablero se ve un poco más complicado. Debería poder identificarse :Icomo el nombre de la placa y haber detectado algunos dispositivos de entrada y salida. Notarás que tenemos dos dispositivos de entrada diferentes, }0y }1. Esto significa que esta función toma 2 entradas. También notará que hay dos instancias del }1dispositivo. Al llamar a la función, ambas celdas contendrán el mismo valor. El }0dispositivo de entrada está directamente encima de un \/dispositivo, esto actúa como un basurero y elimina cualquier canica que caiga sobre él inmediatamente.
Echemos un vistazo a lo que le sucede a una de las canicas colocadas en la placa por los }1dispositivos de entrada:
}1
=9 &1
&0
{>
Caerá en el primer tic y golpeará el =9dispositivo. Esto compara el valor de la canica con 9 y permite que la canica se caiga si el enunciado se =9evalúa. El mármol se empuja hacia la derecha si no. &0y &1son sincronizadores. Se aferran a las canicas que caen sobre ellas hasta que todos los demás &nsincronizadores se llenen también. Como puede esperar, esto condicionalmente desencadenará un comportamiento diferente en alguna otra parte del tablero.
}1 00 01 F7
++ .. &1 &0
&1 &0 {1 {1
{0 //
Si te digo que ++es un incrementador, ya deberías poder decir con qué se llenarán los diferentes sincronizadores. La izquierda &1contendrá el valor de entrada }1+ 1, la &0siguiente contendrá 0 ( 00es un lenguaje literal, representado en hexadecimal). El segundo &1contendrá el valor 1 y el derecho &0se rellena con un F7, que resta 9 de un valor ya que la adición en Marbelous es el módulo 256.
// es un dispositivo deflector que empuja cualquier canica hacia la izquierda en lugar de dejarla caer.
Poner todo esto junto te da esto: si la canica adentro }1es 9, los &0sincronizadores se llenan. Esto hará que el valor 0 caiga en la {0salida y F7(o -9) en la {1salida. Si }1no es 9, {0se rellenará con }1+ 1 y {0contendrá 1. También hay un {>dispositivo, esta es una salida especial que genera una canica junto a una placa en lugar de debajo de ella. Esto se llenará }1si es igual a 9.
@0 @6 00 00 00 @5
}0 &0 &0 &0 &0
>0 @6 &3
\\ -- \/ &2
@0 /\ @4 \/ &1 !!
@4 @1 .. @2 @5 @3
II II II II II II
FF &1 FF &2 FF &3
@1 OO @2 OO @3 OO
Bien, ahora para el grande. Esta placa no tiene un nombre explícito, ya que es la placa principal del archivo. Su nombre implícito es Mb. Deberías poder reconocer algunas células. Hay un dispositivo de entrada, algunos literales de lenguaje ( 00y FF). Hay algunos sincronizadores y hay un deflector. pasemos por esto pieza por pieza.
@0 @6
}0 &0
>0 @6
\\ --
@0 /\ @4
Entonces, el valor de entrada (la entrada de la línea de comando ya que esta es la placa principal) comienza en la segunda celda desde la parte superior donde }0se encuentra. Se caerá y alcanzará el >0dispositivo, que es otro dispositivo de comparación. cualquier canica mayor que 0 cae, cualquier otra canica se empuja hacia la derecha. (dado que las variables Marbelous no están firmadas, solo exactamente 0 será empujado hacia la derecha). Este mármol de valor cero golpeará el @6dispositivo. Este es un portal y transporta la canica a otro portal correspondiente, en este caso justo encima de él. La canica 0 alcanzará el &0sincronizador y activará algunas cosas en otro lugar.
Si la canica no es 0, se cae, se desvía hacia la derecha por \\golpes --que la disminuyen en uno y luego cae sobre /\un clonador. Este dispositivo toma una canica y genera una copia a la derecha y otra a la izquierda. La izquierda se llevará hacia arriba a la otra, @0donde la canica volverá a pasar por la misma secuencia. La izquierda será llevada a otra parte. Esto nos da un bucle, que disminuye la entrada de la línea de comando una vez por bucle y desencadena un comportamiento en cada bucle hasta que alcanza 0. Luego, desencadena algún otro comportamiento.
Echemos un vistazo a lo que sucede con la canica presionada en @4cada bucle.
@4 @1 .. @2 @5 @3
II II II II II II
FF &1 FF &2 FF &3
@1 OO @2 OO @3 OO
Aquí hay 3 literales de lenguaje ( FF), que inmediatamente caerán en portales. Estos portales los llevarán a tres de los IIdispositivos. IIse refiere al tablero :Ique definimos más abajo en el archivo. Como :Itiene 2 dispositivos de entrada distintos, su representación en otra placa debe tener 2 celdas de ancho. Como tenemos 6 celdas que contienen II, podemos decir que tenemos 3 instancias de esta función en el tablero.
Las FFcanicas (o 256 o -1 si lo desea) se sentarán en las celdas de entrada de la :Ifunción esperando hasta que haya suficientes canicas de entrada para iniciar la función (una más). Ahí es donde @4entra el portal. Una copia de la entrada de línea de comando decrementada cae por allí en cada bucle. Esto activará el :Itablero más a la izquierda . Inicialmente con los valores 256 (o -1) y cualquiera que sea la entrada de la línea de comando fue -1. El mármol izquierdo se colocará en los }0dispositivos del :Itablero y el derecho en el }1. Si recuerda lo que hizo este tablero, podrá saber qué resultado tiene. Producirá una versión incrementada de la entrada derecha en la salida izquierda (y convierte un 9 en 0, no en 10) y generará 1 o -9 a la derecha.
El valor incrementado será llevado de vuelta a la celda de entrada derecha por un portal, y el valor de la derecha cae en un sincronizador. Si un sincronizador ya está sosteniendo una canica, las dos canicas chocarán. Las canicas en colisión se suman en el módulo 256. Por lo tanto, los valores en los sincronizadores harán lo siguiente: comienzan vacíos, luego pasan a 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 y luego a 1 de nuevo (ya que se agrega 247 módulo 256).
También es posible que recuerde que una canica sale a la derecha cuando el valor de entrada vuelve a 0. Ya que las :Iplacas están una al lado de la otra, esto activará la placa a la derecha una vez. Esto llenará los tres sincronizadores con valores que son uno más alto de lo que deberían ser para ser una representación de shortlex de la entrada de la línea de comando, para cuando esto haya pasado a 0.
También puede recordar que la :Ofunción convierte un valor en el valor ascii del dígito que representa el valor -1. La salida de estas OOceldas se caerá del tablero, que imprime sus caracteres ascii correspondientes en STDOUT.
00 00 00 @5
&0 &0 &0
&3
\/ &2
\/ &1 !!
@5
Entonces, ¿qué sucede cuando la canica de entrada de línea de comando llega a 0 y llena los &0sincronizadores? bueno, algunas canicas de valor 0 caen y activan los tres sincronizadores que contienen los dígitos (+ 1) del número shortlex en la parte inferior del tablero. &3se activa primero, ya que contiene el dígito más significativo, luego viene &2seguido de &1. Esta canica se teletransporta al otro @5dispositivo antes de eventualmente golpear la !!celda, que termina el tablero.
19, 20, 21, 22en decimales se asigna a08, 09, 10, 11en shortlex. ¡Es por eso que solía confundir eso100 -> 89!