Wyzwanie to opublikowano w ramach wyzwania LotM z kwietnia 2018 r. , A także na drugie urodziny Brain-flak
Myślałem o tym, jaki byłby najskuteczniejszy sposób kodowania programów do wyłamywania mózgów. Oczywistą rzeczą do zrobienia, ponieważ jest tylko 8 prawidłowych znaków, jest mapowanie każdego znaku na 3-bitową sekwencję. Jest to z pewnością bardzo skuteczne, ale wciąż bardzo zbędne. Istnieją pewne cechy kodu wyrywającego mózg, które moglibyśmy wykorzystać, aby skrócić kodowanie.
Nilady, które są reprezentowane przez 2 dopasowane nawiasy, naprawdę działają jak pojedyncza jednostka informacji, a nie 2. Gdybyśmy zastąpili każdy nawias jednym znakiem bajtu, spowodowałoby to, że kodowanie byłoby znacznie mniejsze bez utraty danych.
Ten jest mniej oczywisty, ale bajty końcowe monad są również zbędne. Myślisz, że możesz zgadnąć, co
'?'
przedstawiają postacie w poniższym fragmencie?{(({}?<>?<>?
Jeśli założymy, że wprowadzony kod jest prawidłowy, jest to jedna opcja dla każdego z tych znaków zapytania. Oznacza to, że możemy jednoznacznie użyć znaku zamkniętej monady do przedstawienia każdego zamykającego nawiasu. Ma to dodatkową zaletę polegającą na utrzymywaniu niewielkiego zestawu znaków, co byłoby bardzo pomocne, gdybyśmy chcieli użyć kodowania huffmana. Ponieważ postać z bliskiej monady najprawdopodobniej będzie najczęstszą postacią z szerokim marginesem, może być reprezentowana przez pojedynczy bit, co jest niezwykle wydajne.
Te dwie sztuczki pozwolą nam skompresować kod uderzenia mózgu za pomocą następującego algorytmu:
Zamień każdy wspornik zamykający monady na
|
. Innymi słowy, zamień każdą klamrę zamykającą, która nie jest poprzedzona dopasowaniem otwierającym, na słupek. Więc...(({})<(()()())>{})
stanie się
(({}|<(()()()||{}|
Zastąp każdy nilad wspornikiem zamykającym. Dlatego dopasowane nawiasy klamrowe bez niczego używają następującego mapowania:
() --> ) {} --> } [] --> ] <> --> >
Teraz naszym ostatnim przykładem jest:
((}|<()))||}|
Usuń końcowe
|
znaki. Ponieważ wiemy, że całkowita liczba pasków powinna być równa całkowitej liczbie({[<
znaków, jeśli na końcu brakuje pasków, możemy je wywnioskować. Oto przykład:({({})({}[()])})
stanie się
({(}|(}[)
Twoim dzisiejszym wyzwaniem jest odwrócenie tego procesu.
Biorąc pod uwagę ciąg skompresowanego ataku mózgu zawierającego tylko znaki (){}[]<>|
, rozwiń go do oryginalnego kodu ataku mózgu. Możesz założyć, że dane wejściowe zawsze będą rozszerzane do prawidłowego uderzenia mózgu. Oznacza to, że żaden prefiks wejścia nigdy nie będzie zawierał więcej |
niż ({[<
znaków.
Dane wejściowe nie będą zawierać końcowych |
znaków. Należy je wywnioskować z kontekstu.
Jak zwykle możesz przesłać pełny program lub funkcję, a formaty wejścia / wyjścia są dozwolone. A ponieważ jest to golfowy kod , twój kod będzie oceniany na podstawie długości kodu źródłowego w bajtach, im mniejszy wynik, tym lepiej.
Przypadki testowe
Oto kilka przypadków testowych. Jeśli chcesz więcej, możesz wygenerować własne przypadki testowe za pomocą tego skryptu python i Wiki Brain-Flak , skąd pochodzi większość tych przypadków testowych.
#Compressed code
#Original code
())))
(()()()())
([([}()||||(>||{(})|>|}{((<}|||>}|}>}
([([{}(())])](<>)){({}())<>}{}{((<{}>))<>{}}{}<>{}
({(}|(}[)|||}
({({})({}[()])}{})
(((()))||(](((}}||(}([(((}))||||(]((}}|}|}}|||]||]|[))||(}))|}(}|(}]]|}
((((()()()))([]((({}{}))({}([((({}()())))]([](({}{}){}){}{})))[]))[])[()()])({}()()){}({})({}[][]){}