cérebro , 563 335 318 316 296 + 529 373 366 336 = 632 bytes
Como obviamente faltava uma solução em um idioma relacionado, aqui está a solução no brainfuck e no Golunar. Não consegui postar uma resposta em unário, porque isso precisaria de alguns fantásticos bilhões de vezes mais memória do que existem átomos no universo ^^
A rotina "back" não verifica se o código Golunar / Unário é válido. Se a contagem de bits mod 3! = 1, ocorrerá um loop sem fim imprimindo muitos ">" s.
Agradeço ao Nitrodon por me ajudar a obter abaixo de 300 caracteres para o código unificado do bf
brainfuck para unário
->+>>>>,[>+++[>+++++<-]>[<+<---->>-]<<--[<+>++[<<+>>>[<+>-]<[<->++[<<<+>->+>-[<->--[<<+>>>+++++++++[<----->-]<[<+>--]]]]]]]>[-]>>,]<<<<+[<+]>[>]->+[<]>+[[->+]->[->[<++>-[<++>-[<++>-[<++>-[<-------->>[-]++<-[<++>-]]]]]]<[>+<-]+>>]<<[<<]>[<]>-[[->+]->>+<[<<]>[<]]>+]>[>>]<<[+++++++[>++++++<-]>.<<<]
Experimente online!
e volta
->>,[<++++++[>--------<-]+>>>>>>,]>->-<<<+[-<+]>[[->[->+<[->->+>]<[<<<]>]<+>>>[-<<+>>]<[>>>>++++++++++<<<<-]>>>]>>>+[->+]>-<+[-<+]-<[>>+[->+]-<++[-<+]-<[-]]<<<<<<[<<<<<]>>>>>>[<<]<[->>>]>>]>>>+[->+]<-<+[-[<++>-]<[<++>-]>+++[>+++++<-]>[<+<++++>>-]<<++<[>--<-[>>[<->-]<--<-[>++<-[>+<-[>--<-[>+[>+<-]>[<++>-]<+<-[>++<-]]]]]]]>.[-]>[-]<<<+]
Experimente online!
Golunar / unárias-dígitos, 509 303 288 286 268 + 478 337 331 304 = 572 bytes
brainfuck para unário
2845581296974449674357817038179762273623136917867627972159702240227366875240878616687779429553529795902322625321040063298921498529640547483869509829184440577052825434462245755576011912505085065586076069824710351537537205287083477698633592357950165322060367940923703887
e volta
3775574485023133646619269732540391678811443648964274086227256847322821618228135493733703990523803451383315165001915937932498966394771849173263120467073642011339214182483748816052890450078070151307011943625602391238338941712116968736593594971620990210178757280976709140113340322124688909388916094040773207
Códigos-fonte
brainfuck para unário
[
unary:
><+-.,[]
01234567
62 > 62
60 < -2
45 - 15
43 + 2
44 , 1
46 . 2
91 [ 45
93 ] 2
tape (while reading input): Left tape end marker/LTE, [binary data], input, 15, (15 multiplicator)
tape (while base conversion): LTE, [binary data], Value Start/VS, [decimal digits]
decimal digits: digit used/DU, value
]
- set LTE
>+ set leading 1
>>>>,[ while input
>+++[>+++++<-] set 15 (multiplicator)
>[<+<---->>-] set 15 and decrease input by 60
check for greater than
set current bits = 000 (greater than)
<<--[ if input != 62 try next char
check for less than
<+> set current bits = 001 (less than)
++[ if input != 60 try next char
check for minus
<<+>> set current bits = 011 (minus)
>[<+>-]<[ if input != 45 try next char
check for plus
<-> set current bits = 010 (plus)
++[ if input != 43 try next char
check for comma
<<<+>->+> set current bits = 101 (comma)
-[ if input != 44 try next char
check for dot
<-> set current bits = 100 (dot)
--[ if input != 46 try next char
check for left bracket
<<+>> set current bits = 110 (left bracket)
>+++++++++[<----->-]<[ if input != 91 go to next char
use right bracket
<+> set current bits = 111 (right bracket)
-- decrease input by 2 / should be 0 now
]]]]]]] close all ifs
>[-]>> delete 15 if still existant
, input next character
]
<<<<+[<+]>[>] add one to each bit and delete LTE (for shorter search routine)
Start of binary to decimal routine
- set value start marker (VS)
>+ set digit used marker (DU)
[<] go to LTE
binary to decimal loop: use "double and add algorithm" to calculate the digits of the decimal value
>+[ if not on VS then
[->+]- restore current bit value and go to VS
> go to first DU
[ digit doubling loop
-> remove DU and go to corresponding digit
[
<++>- decrement current value and add 2 to temp value four times
[
<++>-
[
<++>-
[
<++>-
[ if value was greater than 4 then
<---- ---- subtract 8 from temp
>>[-]++ set next digit temp = 2 (DU plus 1)
<- decrement current digit
[<++>-] set temp = remaining value * 2
]
]
]
]
]
<[>+<-] set current digit = temp
+ set DU
>> go to next digit
] end of digit doubling loop
<<[<<]>[<]> go to current bit
-[ if bit is 2 (used plus 1)
[->+]- delete bit and go to VS
>>+ increment least significant digit
<[<<]>[<] go to current bit
]
>+ if not on VS then repeat
] end of binary to decimal loop
>[>>]< go to most significant digit
<[ printing loop: for each DU print corresponding value
+++++++[>++++++<-]>. add 48 to value (ASCII 0) and print
<<< go to next DU
]
e volta
[
tape: left tape end marker/LTE(-1), [digits], digit end marker/DE(0), carry, SB(-1), [binary data], 60, 15
digits: digit used marker/DU(1), digit, remainder, solution, 0
else] [exit else, exit if
binary data: value (, else, exit if, exit else)
]
input decimal value
->> set LTE
,[ while input
<++++++[>--------<-] decrease input by 48
+ set DU
>>>>> >, input next digit
]
>->- set start of bits (SB) and first CCB
<<<+[-<+]> delete LTE and go to first DU
division loop: calculate the remainders of the input divided by 2 repeatedly to get the (inverted) bits
[
divide each digit by 2
[ for each DU
- delete DU (for exit if)
> go to digit
[->+< dec digit / set remainder
[->->+>] if digit gt 0: dec digit / del remainder / inc solution / goto 0
pointer: (value(0) remainder is set) or (0 solution gt 1)
<[<<<] go to DU
> go to digit
]
<+ set DU
>>>[-<<+>>] move solution to digit
<[ if remainder
>>>> go to next digit
+++++ +++++ add 10 to digit/carry
<<<<- go back and delete remainder
]
>>> go to next DU
]
append new bit
>>>+[->+] go to and delete CCB
>- set new CCB
<+[-<+]-< go to carry
[ if carry
>>+[->+]-<+ set last bit
+[-<+]-<[-] go to and clear carry
]
check if first digit became 0 / neccessary to check if value has been completely processed
< <<<<<[<<<<<]>>>>> go to first DU
>[ if digit gt 0
<< go to exit if
]<[ else
- delete DU
>>> go to exit else of next digit
]
>> go to DU / DE if all digits processed
] end of division loop
decode binary values
>>>+[->+] go to and delete CCB (after last bit)
<- delete leading 1
< go to first bit
Start of bit decoder
[
unary:
><+-.,[]
01234567
62 > 62
60 < -2
43 + -17
45 - 2
46 . 1
44 , -2
91 [ 47
93 ] 2
tape: start of bytes marker/SB(-1), [binary data], 60(print char/PC), 15
]
+[- while not SB
Set least significant to octal value of three bits
[<++>-] if first bit set add 2 to second bit
<[<++>-] for each second bit add 2 to third bit
>+++[>+++++<-] multiplier 15
>[<+<++++>>-] setup table 60 15
run through the 8 possibilities
0 greater than
<<++ set PC = 62 (greater than)
<[ if value gt 0 go to next char
1 less than
>-- set PC = 60 (less than)
<-[ if value gt 1 go to next char
2 plus
>>[<->-]<-- set PC = 43 (plus)
<-[ if value gt 1 go to next char
3 minus
>++ set PC = 45 (minus)
<-[ if value gt 1 go to next char
4 dot
>+ set PC = 46 (dot)
<-[ if value gt 1 go to next char
5 comma
>-- set PC = 44 (comma)
<-[ if value gt 1 go to next char
6 left bracket
>+[>+<-]>[<++>-]<+ set PC = 91 (left bracket) (inc (45) / double (90) / inc (91))
<-[ if value gt 1 go to next char
7 right bracket
>++ set PC = 93 (right bracket)
<- decrease value the last time to exit if
]]]]]]] close all ifs
>.[-] print char and clear PC
>[-] clear 15 if still existant
<<< go to next bits
+ repeat if not SB
]