Este desafío se publicó como parte del desafío LotM de abril de 2018 , así como para el segundo cumpleaños de Brain-flak
Estaba pensando en cuál sería la forma más eficiente de codificar programas de ataque cerebral. Lo obvio, ya que solo hay 8 caracteres válidos, es asignar cada carácter a una secuencia de 3 bits. Esto es ciertamente muy efectivo, pero aún es muy redundante. Hay algunas características del código brain-flak que podríamos aprovechar para acortar la codificación.
Los nilads, todos representados por 2 paréntesis coincidentes, realmente actúan como una sola unidad de información en lugar de 2. Si reemplazamos cada paréntesis con un solo carácter de byte, esto haría que las codificaciones sean mucho más pequeñas sin perder ningún dato.
Este es menos obvio, pero los bytes de cierre de las mónadas también son redundantes. ¿Crees que podrías adivinar qué
'?'
representan los personajes en el siguiente fragmento?{(({}?<>?<>?
Si asumimos que la entrada es un código válido de brain-flak, entonces solo hay una opción para cada uno de esos signos de interrogación. Esto significa que podemos usar inequívocamente un carácter de mónada cercano para representar cada paréntesis de cierre. Esto tiene el beneficio adicional de mantener pequeño el conjunto de caracteres, lo que sería de gran ayuda si quisiéramos usar una codificación huffman. Dado que el carácter de mónada cercana probablemente será el personaje más común por un amplio margen, podría representarse con un solo bit, lo que es muy eficiente.
Estos dos trucos nos permitirán comprimir el código brain-flak a través del siguiente algoritmo:
Reemplace cada soporte de cierre de una mónada con
|
. O, en otras palabras, reemplace cada corchete de cierre que no esté precedido por su partido de apertura con una barra. Asi que...(({})<(()()())>{})
se convertiría
(({}|<(()()()||{}|
Reemplace cada nilad con su soporte de cierre. Por lo tanto, los corchetes coincidentes sin nada en ellos usan la siguiente asignación:
() --> ) {} --> } [] --> ] <> --> >
Ahora nuestro último ejemplo se convierte en:
((}|<()))||}|
Eliminar
|
caracteres finales . Como sabemos que el número total de barras debe ser igual al número total de({[<
caracteres, si faltan barras al final, podemos inferirlas. Entonces un ejemplo como:({({})({}[()])})
se convertiría
({(}|(}[)
Su desafío para hoy es revertir este proceso.
Dada una cadena de ataques cerebrales comprimidos que contiene solo los caracteres (){}[]<>|
, amplíelos al código original de ataques cerebrales. Puede suponer que la entrada siempre se expandirá a una falla mental válida. Esto significa que ningún prefijo de la entrada contendrá más |
que ({[<
caracteres.
La entrada no contendrá |
caracteres finales . Estos deben inferirse del contexto.
Como de costumbre, puede enviar un programa completo o una función, y los formatos de entrada / salida son permisivos. Y dado que este es un código de golf , su código se puntuará por la longitud del código fuente en bytes, cuanto menor sea la puntuación, mejor.
Casos de prueba
Aquí hay algunos casos de prueba. Si desea más, puede generar sus propios casos de prueba con este script de Python y el Wiki Brain-Flak , de donde proviene la mayoría de estos casos de prueba.
#Compressed code
#Original code
())))
(()()()())
([([}()||||(>||{(})|>|}{((<}|||>}|}>}
([([{}(())])](<>)){({}())<>}{}{((<{}>))<>{}}{}<>{}
({(}|(}[)|||}
({({})({}[()])}{})
(((()))||(](((}}||(}([(((}))||||(]((}}|}|}}|||]||]|[))||(}))|}(}|(}]]|}
((((()()()))([]((({}{}))({}([((({}()())))]([](({}{}){}){}{})))[]))[])[()()])({}()()){}({})({}[][]){}
fuente
Respuestas:
Cerebro-Flak ,
952 916818 bytesAhorró 360 bytes calculando paréntesis opuestos relativamente en lugar de hacerlo desde cero (por ejemplo,
')'
= en'(' + 1
lugar de(((5 * 2) * 2) * 2) + 1
)Guardado 34 bytes con algunos reemplazos directos de DJMcMayhem
Se guardaron 10 bytes superponiendo el
>]}
código de manejoAhorró 118 bytes al deduplicar rollos
Ahorró 40 bytes aprovechando la pila vacía para simplificar el primer rollo
Ahorró 48 bytes marcando EOF con -1, lo que permite un código de rollo más conciso
Ahorré 36 bytes usando la lógica de stock igual en lugar de la mía
Ahorró 98 bytes gracias a que Jo King encontró una manera más eficiente de construir la salida
Pruébalo en línea!
Golf por primera vez en Brain-Flak, por lo que probablemente haya algunas mejoras realmente grandes, pero funciona. Un montón de copiar / pegar para manejar cada tipo de soporte, y muchas gracias al generador de enteros automático y el fragmento de rollo desde aquí .
Explicación aquí , TIO lo formatea más fácilmente
Respuesta extra:
Brain-Flak comprimido 583 bytes
Pruébalo en línea!
(Tenga en cuenta que el enlace anterior no se ejecuta porque TIO no tiene un intérprete Compressed Brain-Flak. Puede encontrar un transpilador para Brain-Flak aquí )
He comprobado que esto es válido al transpirar a Brain-Flak con esta herramienta, ahora lo suficientemente eficiente como para que el tiempo de espera sea poco probable.
fuente
<>(<()>)
con(<>)
. Además, puede cambiar(<>{}<>)(<()>)
a(<(<>{}<>)>)
Retina 0.8.2 ,
10398 bytesPruébalo en línea! El enlace incluye casos de prueba. Editar: guardado 5 bytes con la inspiración de @MartinEnder. Explicación:
Coloque un
;
corchete después de cada cierre y cámbielos a todos para abrir los corchetes, y cambie los|
s a;
s también.Cuente el número de paréntesis abiertos sin igual y agregue esa cantidad de
;
s.Copie cada paréntesis de apertura en su correspondencia
;
.Voltee los corchetes copiados y elimine el
;
s.fuente
|
a algo así!
. No sería incluso bytes costaría si usted traduce>-}
a<-{
(que creo que daz
para|
).z
pero de todos modos se me ocurrió reducir algunos bytes más.TIS ,
670666 bytes-4 bytes para saltar hacia adelante para saltar hacia atrás
Código:
Diseño:
Pruébalo en línea!
Dudo que sea más pequeño, pero no veo una manera de hacerlo más pequeño. Desafortunadamente, todos los
NOP
s parecen necesarios para el tiempo, y no puedo poner la pila donde@14
está actualmente debido a la lectura desdeANY
adentro@11
.La estructura de esta solución es la siguiente:
Al ver un paréntesis abierto, el abierto se envía a lo largo de la columna izquierda para que salga, y el cierre se envía a lo largo de la columna derecha a la pila.
Al ver una llave de cierre, tanto la apertura como el cierre se envían a lo largo de la columna izquierda para su salida.
Al ver una tubería, la pila se abre y se envía a la salida.
En EOF,
@1
comenzará a leer desde@2
, en lugar de la secuencia de entrada desde@0
.@2
produce un flujo interminable de tuberías, por lo que la pila se drenará.Una vez que la entrada y la pila están agotadas, el programa se detiene.
Advertencia: debido a las limitaciones de TIS, el tamaño de la pila está limitado a 15. Si hay algo anidado más profundo que eso, esta implementación producirá un resultado incorrecto.
fuente
JavaScript (ES6), 107 bytes
Toma la entrada como una matriz de caracteres. Devuelve una cadena.
Pruébalo en línea!
fuente
Haskell,
127121 bytesPruébalo en línea!
Editar: -6 bytes usando la función de @ Laikoni para encontrar el paréntesis correspondiente .
fuente
Ruby , 104 bytes
Este es un programa completo que sale a la consola.
(i<5?a:$>)<<r[-i]
tiene que ser uno de los mejores campos de golf que he hecho.Pruébalo en línea!
Ruby , 106 bytes
Esta es mi primera solución. Una función lambda anónima que toma y devuelve cadenas.
Pruébalo en línea!
fuente
Brain-Flak ,
606 548 496 418 394390 bytesPruébalo en línea!
Comencé esto jugando al golf con la respuesta de Kamil Drakari , pero se me escapó hasta el punto en que decidí publicarla como una respuesta separada.
Explicación:
Y por supuesto...
Brain-Flak comprimido, 285 bytes:
fuente
Java 10, 424 bytes
Es un poco largo, pero no pude descubrir cómo acortarlo aún más. Sin embargo, este es un buen desafío.
Pruébelo en línea aquí .
Versión sin golf:
fuente
Python 2,
188184180177174173 bytesGuardado 4 bytes gracias a DJMcMayhem.
Pruébalo en línea!
fuente
s
termina vacío. De lo contrario, terminas con los caracteres adicionales en el extremo equivocado.Python 3 , 122 bytes
Pruébalo en línea!
fuente
Haskell , 152 bytes
Pruébalo en línea! o verificar todos los casos de prueba .
p
implementa un analizador recursivo, que podría ser más de matar para la gramática simple.fuente
m
para encontrar el soporte correspondiente.Python 2 , 244 bytes
Pruébalo en línea!
Tomó más de una o dos horas para que esto funcionara ...
fuente