¡Esta pregunta es la primera de varios desafíos de cumpleaños de Brain-flak diseñados para celebrar el primer cumpleaños de Brain-Flak! Puede encontrar más información sobre el cumpleaños de Brain-Flak aquí
El verano pasado tuvimos el Brain-flak Integer Metagolf , y las respuestas que generó han sido muy útiles para la comunidad Brain-Flak desde entonces. Lo principal que hace que Integer Metagolf sea tan eficiente es una técnica llamada Multiplicación de hardcoding.
En Brain-Flak, la multiplicación en tiempo de ejecución es extremadamente costosa. El fragmento de multiplicación más corto conocido es:
({}<>)({<({}[()])><>({})<>}{}<><{}>)
Descubierto por Megatom
Sin embargo, hay una manera muy simple de crear una multiplicación de tiempo de compilación. Por ejemplo, el siguiente código se multiplicará por 5:
(({})({})({})({}){})
Esto funciona porque las expresiones consecutivas se agregan juntas. Cada uno ({})
no hace nada a la pila ( {}
aparece y lo (..)
empuja hacia atrás) y se evalúa según lo que esté encima de la pila. Todas estas expresiones juntas suman hasta cinco veces lo que haya en la parte superior de la pila.
Para cualquiera de n
las siguientes expresiones de cadena, se creará un fragmento que multiplicará la parte superior de la pila por n
:
"("+"({})"*(n-1)+"{})"
Esto funciona al hacer n
expresiones que todos evalúan en la parte superior de la pila. El primero en n-1
realidad no cambia nada y el último elimina la parte superior de la pila antes del empuje.
Para números compuestos, puede encadenar varias expresiones más pequeñas juntas para guardar bytes. Por ejemplo, puedes multiplicar por 25 multiplicando por 5 dos veces:
(({})({})({})({}){})(({})({})({})({}){})
Esto es bastante simple, y para algunos números funciona bastante bien, sin embargo, hay mejores maneras de hacerlo. Por ejemplo, un método que se me ocurrió utiliza la representación binaria del número. ( Aquí hay una implementación de Python ). Este nuevo método es mucho más efectivo que la simple expresión de cadena mostrada anteriormente, pero no es el final, hay todo tipo de formas interesantes para codificar la multiplicación y probablemente una tonelada que aún nadie ha descubierto.
Así que creo que es hora de ver qué tan buenos podemos ser.
Breve descripción de Brain-Flak
Aquí hay una descripción de todo lo que necesitará saber sobre Brain-Flak para este desafío.
Brain-Flak tiene "nilas" y "mónadas". Nilads son paréntesis que no tienen nada dentro de ellos. Cada nilad hace una cosa y devuelve un valor. Para este desafío, las dos nilas que nos interesan son {}
y <>
. {}
abre la parte superior de la pila activa y devuelve su valor. <>
cambia la pila activa y la pila activa en, de modo que la pila activa se vuelve inactiva y la pila inactiva se vuelve activa, devuelve cero.
Las mónadas son paréntesis con cosas dentro de ellas. Toman un solo argumento, la suma de todo lo que hay dentro de ellos, a veces realizan una acción y luego devuelven un valor. Los tres de estos que nos interesan son (...)
, <...>
y [...]
. La mónada más importante para este desafío (...)
toma el valor del interior y lo empuja a la pila activa. Luego devuelve el argumento. <...>
y [...]
son mónadas "inertes", es decir, no realizan ninguna acción, sino que modifican el valor que se les pasa. <...>
siempre devuelve cero independientemente del argumento pasado. Mientras tanto, [...]
siempre devuelve los tiempos de discusión -1
.
Programas de muestra con explicación
Si nunca ha programado en Brain-Flak, podría ser una buena idea mirar algunos programas de ejemplo utilizando las operaciones descritas
({}{})
Esto agrega los dos números superiores en la pila. Cada uno {}
saca un valor de la pila y (...)
empuja su suma hacia atrás.
({}[{}])
Del mismo modo, esto resta el segundo elemento de la pila del primero. Al igual que antes de que cada uno {}
muestre un valor, pero [..]
alrededor del segundo hace que se agregue. Una vez más, (...)
empuja la suma.
({}<{}>)
Esto elimina el segundo valor en la pila manteniendo intacto el valor superior. Funciona igual que los dos últimos, excepto que el segundo valor es silenciado por, por <...>
lo que el empuje solo empuja el primer valor hacia atrás.
(({}))
Esto hace una segunda copia del valor en la parte superior de la pila. Lo hace haciendo estallar la parte superior de la pila al {}
obtener su valor, el primero (..)
luego lo empuja hacia atrás evaluando su valor. El segundo (...)
toma el valor devuelto por el primero y lo empuja a la pila también. creando una segunda copia.
Tarea
Dado un número entero, n
cree un fragmento Brain-Flak limpio de pila que multiplique la parte superior de la pila actual por n
.
Se le permite usar las siguientes operaciones de Brain-Flak
(...) -> Push Monad, Pushes the result of its contents
<...> -> Zero Monad, Returns zero
[...] -> Negative Monad, Returns the opposite of its contents result
{} -> Pop nilad, Pops the TOS and returns its value
<> -> Switch nilad, Switches the active and inactive stack
Las otras operaciones están prohibidas a los efectos del desafío.
Puntuación
Su puntaje será la duración acumulada de todos los programas desde n=2
hasta n=10000
. Asegúrese de incluir un enlace a la salida de su programa para su verificación.
fuente
[...]
, así que es un comienzo.Respuestas:
Rubí, 669856
Esta es una respuesta de referencia rápida. Primeros 1000 programas min encontrados aquí . (Intenté publicarlos todos, pero eso sobrecargó el tamaño máximo de pastebin.) Puedo agregar una explicación de código más adelante.
Ejemplos:
fuente