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
())))
(()()()())
([([}()||||(>||{(})|>|}{((<}|||>}|}>}
([([{}(())])](<>)){({}())<>}{}{((<{}>))<>{}}{}<>{}
({(}|(}[)|||}
({({})({}[()])}{})
(((()))||(](((}}||(}([(((}))||||(]((}}|}|}}|||]||]|[))||(}))|}(}|(}]]|}
((((()()()))([]((({}{}))({}([((({}()())))]([](({}{}){}){}{})))[]))[])[()()])({}()()){}({})({}[][]){}