Ce défi a été publié dans le cadre du défi LotM d'avril 2018 , ainsi que pour le deuxième anniversaire de Brain-flak
Je réfléchissais à la façon la plus efficace de coder les programmes de brain-flak. La chose évidente à faire, puisqu'il n'y a que 8 caractères valides, est de mapper chaque caractère sur une séquence de 3 bits. C'est certainement très efficace, mais c'est toujours très redondant. Il existe certaines fonctionnalités du code brain-flak dont nous pourrions profiter pour raccourcir l'encodage.
Les nilades, qui sont toutes représentées par 2 parenthèses appariées, agissent vraiment comme une seule unité d'information plutôt que 2. Si nous remplaçions chaque parenthèse par un caractère à un octet, cela rendrait les encodages beaucoup plus petits sans perdre de données.
Celui-ci est moins évident, mais les octets de fermeture des monades sont également redondants. Vous pensez pouvoir deviner ce que les
'?'
personnages représentent dans l'extrait de code suivant?{(({}?<>?<>?
Si nous supposons que l'entrée est un code de flak de cerveau valide, il n'y a qu'une seule option pour chacun de ces points d'interrogation. Cela signifie que nous pouvons sans ambiguïté utiliser un caractère de monade proche pour représenter chaque parenthèse fermante. Cela a l'avantage supplémentaire de garder le jeu de caractères petit, ce qui aiderait grandement si nous voulions utiliser un encodage huffman. Étant donné que le caractère de monade proche sera très probablement le caractère le plus courant sur une large marge, il pourrait être représenté par un seul bit, ce qui est extrêmement efficace.
Ces deux astuces nous permettront de compresser le code brain-flak via l'algorithme suivant:
Remplacez chaque support de fermeture d'une monade par
|
. Ou en d'autres termes, remplacez chaque parenthèse fermante qui n'est pas précédée par son match d'ouverture par une barre. Alors...(({})<(()()())>{})
deviendrait
(({}|<(()()()||{}|
Remplacez chaque nilad par son support de fermeture. Par conséquent, les crochets assortis sans rien utilisent le mappage suivant:
() --> ) {} --> } [] --> ] <> --> >
Maintenant, notre dernier exemple devient:
((}|<()))||}|
Supprimez les
|
caractères de fin . Parce que nous savons que le nombre total de barres doit être égal au nombre total de({[<
caractères, s'il manque des barres à la fin, nous pouvons les déduire. Donc, un exemple comme:({({})({}[()])})
deviendrait
({(}|(}[)
Votre défi pour aujourd'hui est d'inverser ce processus.
Étant donné une chaîne de brain-flak compressée contenant uniquement les caractères (){}[]<>|
, développez-la dans le code original de brain-flak. Vous pouvez supposer que l'entrée se développera toujours en un flak de cerveau valide. Cela signifie qu'aucun préfixe de l'entrée ne contiendra jamais plus |
de ({[<
caractères.
L'entrée ne contiendra pas de |
caractères de fin . Ceux-ci doivent être déduits du contexte.
Comme d'habitude, vous pouvez soumettre un programme complet ou une fonction, et les formats d'entrée / sortie sont permissifs. Et comme il s'agit d'un code-golf , votre code sera marqué par la longueur du code source en octets, plus le score est petit, mieux c'est.
Cas de test
Voici quelques cas de test. Si vous en voulez plus, vous pouvez générer vos propres cas de test avec ce script python et le Wiki Brain-Flak , d'où provient la majorité de ces cas de test.
#Compressed code
#Original code
())))
(()()()())
([([}()||||(>||{(})|>|}{((<}|||>}|}>}
([([{}(())])](<>)){({}())<>}{}{((<{}>))<>{}}{}<>{}
({(}|(}[)|||}
({({})({}[()])}{})
(((()))||(](((}}||(}([(((}))||||(]((}}|}|}}|||]||]|[))||(}))|}(}|(}]]|}
((((()()()))([]((({}{}))({}([((({}()())))]([](({}{}){}){}{})))[]))[])[()()])({}()()){}({})({}[][]){}