7
\$\begingroup\$

You don't need to know these languages to participate. All necessary information has been provided in this question.

You should write a program or function which given a brainfuck (BF) code as input outputs its tinyBF equivalent.

BF has 8 instructions characters: +-><[],. and tinyBF has 4: =+>|. Converting works the following way: starting from the beginning of the BF code each symbol is replaced by on of its two tinyBF counterparts based on the number of = signs in the tinyBF code until that point (i.e. = behaves like a toggle switch).

The converter table (with columns: Brainfuck symbol; tinyBF symbol(s) when ther are even ='s before; tinyBF symbol(s) when ther are odd ='s before):

BF even odd + + =+ - =+ + > > => < => > [ | =| ] =| | . == == , |=| =|=| 

(This creates an almost unique tinyBF code. The only conflict occurs if the BF code contains a [] which is generally unused as it creates an infinite void loop.)

Input

  • An at least 1 byte long valid brainfuck program containing only the characters +-><[],.
  • Guaranteed not to contain the string []
  • Trailing newline is optional.

Output

  • A tinyBF program.
  • Trailing newline is optional.

Examples

You can convert any BF program to tinyBF with this (1440 byte long) converter (see the Edit section for a small deviation).

Format is Input into Output ++- into ++=+ ,[.,] into |=||==|=|=| or |=|=|==|=|| (both is acceptable check the Edit section) >++.--.[<]+-, into >++===++===|=>|=+=+=|=| >++-+++++++[<+++++++++>-]<. into >++=+=+++++++|=>=+++++++++>=+|>== 

Edit

As @Jakube pointed out in the official tinyBF converter in the equivalents of the , BF instruction (|=| and =|=|) the last = signs aren't counted towards the toggle state. Both the official and mine interpretations are acceptable but you have to choose one.

This is code-golf so the shortest entry wins.

\$\endgroup\$
9
  • \$\begingroup\$ By 'odd' and 'even', do you mean the first character of the BF code is 'odd', the next is 'even', and so on? \$\endgroup\$ Commented Apr 8, 2015 at 18:14
  • \$\begingroup\$ @ASCIIThenANSI I think what's meant is the number of = characters output before the character currently being translated. Think of the = character as a toggle between two instruction sets. \$\endgroup\$ Commented Apr 8, 2015 at 18:20
  • \$\begingroup\$ @orip OK, but what about things like =|=| that don't change the even/odd value? Or is that part of the challenge? \$\endgroup\$ Commented Apr 8, 2015 at 18:22
  • \$\begingroup\$ Is input through a file, STDIN, or our choice? \$\endgroup\$ Commented Apr 8, 2015 at 19:26
  • \$\begingroup\$ @ASCIIThenANSI Your choice. \$\endgroup\$ Commented Apr 8, 2015 at 19:32

8 Answers 8

14
\$\begingroup\$

Extended BrainFuck 276 bytes

(not counting uneccesary linefeeds)

{a<<]>&c}{b<<-]<[->}{c]<]>[>[}{d 4+[-<}3>4->3->5->-->>&d 4+>]<[-< 4+<3+<4+<8+4>]<[<]<<,[>3+&d 6->]+<-[-[-[-[14-[--[>&d 6->]+<+[--[[ -]>[-&c>.&b>>.<.<+&a->>.<.&b>.<&a->>.>>.3<&b 4>.4<&a 4>.3<&b+>>.> >.6<]>]<]>[-3>..3<&c 3>.<<&b+>>.>.3<&a>>.<.>.<.&b+>.>.<.<&a->>.>. <<&b 3>.5<]>]<,] 

How to compile and run:

beef ebf.bf < tinybf.ebf > tinybf.bf beef tinybf.bf < source.bf > source.tbf 

It will work with any wrapping BF interpreter that uses/support 0 as EOF. Actual EBF source before golfing:

:i:f:o:p:e:a:g $p ~"|=+>"<[<]@o $i,( $f+++++++(-$i------)+$i-; + ($i-; , ($i-; - ($i-; . ($i--------------; < ($i--; > ($f++++(-$i------)+$i+; [ ($i--; ] ((-) $f(-) ) $f ( $o[$p.$f-]<[@f-$e.$p.$o+$i] ) ; ] ) $f ( $o[-$e.$p.$f-]<[@f-$p.$i] ) ; [ ) $f ( $o[-$e.$g.$f-]<[@f-$g.$i] ) ; > ) $f ( $o[$g.$f-]<[@f-$o+$e.$g.$i] ) ; < ) $f (- $e.. ) ; . ) $f ( $o[$a.$f-]<[@f-$o+$e.$a.$i] ) ; - ) $f ( $o[$e.$p.$e.$p.$f-]<[@f-$o+$p.$e.$p.$i] ) ; , ) $f ( $o[-$e.$a.$f-]<[@f-$a.$i] ) ; + $i,) 

BrainFuck 404 bytes

This is the trimmed output of the compiled EBF.

>>>---->--->----->-->>++++[-<++++>]<[-<++++<+++<++++<++++++++>>>>]< [<]<<,[>+++++++[-<------>]+<-[-[-[-[--------------[--[>++++[-<----- ->]+<+[--[[-]>[-]<]>[>[>.<<-]<[->>>.<.<+<<]>]<]>[>[->>.<.<<-]<[->>. <<<]>]<]>[>[->>.>>.<<<<<-]<[->>>>>.<<<<<<]>]<]>[>[>>>>.<<<<<-]<[->+ >>.>>.<<<<<<]>]<]>[->>>..<<<]<]>[>[>>>.<<<<-]<[->+>>.>.<<<<<]>]<]>[ >[>>.<.>.<.<<-]<[->+>.>.<.<<<]>]<]>[>[->>.>.<<<<-]<[->>>>.<<<<<]>]<,] 
\$\endgroup\$
1
  • \$\begingroup\$ So it's converting BF to TinyBF... in BF. That's AWESOME. \$\endgroup\$ Commented Apr 9, 2015 at 19:04
4
\$\begingroup\$

CJam, 50 bytes

l{"..+-><[],"#2mdT2$@T?:T=L'=?"== + > | |=|"S/@=}/ 

Try <[],"#2mdT2$@T?:T=L'=?"== + > | |=|"S/@=}/&input=>++.--.[<]+-," rel="nofollow">one example or <[],"#2mdT2$@T?:T=L'=?"== + > | |=|"S/@=}/]oNo}/&input=++-,[.,]>++.--.[<]+-,>++-+++++++[<+++++++++>-]<." rel="nofollow">all of them online.

Explanation

The magic is in the mapping! Looking up each operator's index in a carefully ordered yet simple string produces three useful pieces of information at once: whether the operator is directionless (index == 0), the direction the operator requires (index mod 2), and the index of the output operator (index / 2).

Using that handy mapping, it's a simple case of looping through each input operator and producing a direction swap operator if the direction needs to be changed, updating the direction, and producing the output operator.

l "Read a line of input."; { "For each character of input:"; "..+-><[],"# "Map the character: '.' -> 0 | '+' -> 2 | '-' -> 3 '>' -> 4 | '<' -> 5 '[' -> 6 | ']' -> 7 ',' -> 8 | "; 2md "Calculate the quotient and remainder of the mapping divided by 2."; T2$@T?:T "If the the mapping is nonzero (not '.'), set the direction after this operator to the remainder above. Otherwise ('.'), don't change the direction."; =L'=? "If the direction before this operator is equal to the direction after, produce an empty string. Otherwise, produce the direction switch operator, '='."; "== + > | |=|"S/@= "Map the previous mapping divided by 2 to an operator: 0 ('.') -> '==' 1 ('+', '-') -> '+' 2 ('>', '<') -> '>' 3 ('[', ']') -> '|' 4 (',') -> '|=|' "; }/ 
\$\endgroup\$
2
\$\begingroup\$

TinyBF***, 558 bytes

Don't credit me for this, this is the TinyBF version of @Sylwester's BrainF*** answer (I used his code to convert his code into this code, :P). I just felt the need to put this answer up.

>>>=++++=>=+++=>=+++++=>=++=>>++++|=+>=++++>=|>=|=+>=++++=>=+++=>=++++=>=+++++++ +>>>>=|>=|=>|>>=|=|=|>+++++++|=+>++++++=>=|=+=>+=|=+=|=+=|=+=|=++++++++++++++=|= ++=|>++++|=+>++++++=>=|=+=>=+|=++=||=+|=>|=+|>|=>|>|>===>>+|>=|=+=>>>===>==>=+=> >|=>=|>|=>|>|=+=>>===>==>>+|>=|=+=>>===>>>|=>=|>|=>|>|=+=>>==>>===>>>>>+|>=|=+=> >>>>===>>>>>>|=>=|>|=>|>|>>>>===>>>>>+|>=|=+=>+>>==>>===>>>>>>|=>=|>|=>|=+=>>>== ===>>>|>|=>|>|>>>===>>>>+|>=|=+=>+>>==>===>>>>>|=>=|>|=>|>|>>===>===>===>==>>+|> =|=+=>+>==>===>==>>>|=>=|>|=>|>|=+=>>==>===>>>>+|>=|=+=>>>>===>>>>>|=>=|>=|=|| 
\$\endgroup\$
1
\$\begingroup\$

Perl, 244 241 226 217 bytes

open(B,$ARGV[0]);%e=qw(+ + - =+ > > < => [ | ] =| . == , |=|);%o=qw(+ =+ - + > => < > [ =| ] | . == , =|=|);$q=0;while(<B>){$p='';@c=split('');foreach$c(@c){if($q%2>0){$p.=$o{$c}}else{$p.=$e{$c};}$q=$p=~/=/g;}print$p} 

Works on all cases. Run with perl file.pl [filename] where file.pl is the name of the program, and [filename] is the name of the BF file.
Changes

  • Saved 3 bytes by using split('') instead of split('',$_).
  • Saved 15 bytes by:
    • Getting rid of $f= in front of open (3 bytes)
    • Replacing if($eo%2==1) with if($eo%2>0) (1 byte)
    • Replacing $p=$p. with $p.= (2 bytes * 2 times = 4 bytes)
    • Removing trailing newline, as it was optional (5 bytes)
    • Removed =() (3 bytes)
  • Saved 9 bytes by shortening variable names.
\$\endgroup\$
0
1
\$\begingroup\$

K, 91 bytes

o:0;{:[i:"..+-><[],"?x;t:i!2;t:0];`0::[o=t;"";"="],("==";"+";">";"|";"|=|")@i%2;o::t}',/0:` 

It's more-or-less a direct port of @Runer112's CJam answer. And it's much longer. Life sucks.

\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 129 bytes

b=>[...b].map(x=>p+="=+,+,=>,>,=|,|,==,=|=|,+,=+,>,=>,|,=|,==,|=|".split`,`["+-><[].,".indexOf(x)+p.split`=`.length%2*8],p="")&&p 

Uses an array of the 16 possibilities (8 characters times 2 parities), and indexes into this. The array is built by splitting a string, which saves 26 bytes over an array.

\$\endgroup\$
0
\$\begingroup\$

Ruby, 233 217 bytes

p,m,g,l,b,s,d,a,q,f=%w(+ - > < [ ] . , | =) z=[{p=>p,m=>f+p,g=>g,l=>f+g,b=>q,s=>f+q,d=>f+f,a=>q+f+q},{p=>f+p,m=>p,g=>f+g,l=>g,b=>f+q,s=>q,d=>f+f,a=>f+q+f+q}] i=0 ARGV[0].each_char{|c|v=z[i%2][c];print v;i+=v.count(f)} 

An 8-byte improvement on the previous non-esoteric answers!
Saved 16 bytes with the %w() syntax

\$\endgroup\$
0
\$\begingroup\$

Ruby, 101 bytes

->s{t="";s.chars{|c|t<<((t.count(?=)+i="..+-><[],".index(c))%2<1&&i>0?"":?=)+%w(= + > | |=|)[i/2]};t} 

Try it online!

Uses the second interpretation of the ambiguous , translation rule.

\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.