Nameless to Brainf**k converter

7

1

This is inspired by the Brainf*** to tinyBF converter challenge.

Brainf**k (which will be henceforth referred to as BF) is a well-known estoric programming language, so I won't go over it too much here.

Nameless language is a binary-looking version of BF. See the linked page for more info.

Your challenge is to implement a golfed Nameless-to-BF converter. It should implement all of the commands except for 1100 (which isn't really possible to implement in BF) and 1010 (that isn't really possible, either). Any characters other than 1's and 0's should be ignored because they can be used for comments (after all, you wouldn't want an unreadable program, right? ;).

Here's a simple table of a Nameless -> BF mapping:

0000 -> >
0001 -> <
0010 -> +
0011 -> -
0100 -> .
0101 -> ,
0110 -> [
0111 -> ]
1011 -> [-]
1000 -> adds the base 10 value of the next command to the current memory cell (see below)
1001 -> subtracts the base 10 value of the next command from the current memory cell (see below)

NOTE: I accidentally flipped < and >. Thanks to @IlmariKaronen for pointing that out.

For 1000 and 1001, you can directly implement it in the translator. For instance, this:

1000 0010

could be written as:

++

The translator determined the value of the next command in advance and wrote it out.

Invalid sequences (e.g. 1111) and the presence of 1000/1001 at the end of the program are undefined; you don't have to handle them.

MAY THE GOLFING BEGIN!!!

kirbyfan64sos

Posted 2015-04-09T19:00:44.503

Reputation: 8 730

Is it supposed to be binary? eg. 3 == 51 == 00110011 == --??? – Sylwester – 2015-04-10T01:38:11.190

OK, I looked it up. + in BF increments the current cell by 1 (so if the current cell has a value of 2, + would make it 3.) 1000 0100 does become ++++++++ and 1001 0100 becomes ---------. I'm also assuming 1000/1001 at the end of a line is also undefined. – ASCIIThenANSI – 2015-04-10T14:24:33.253

@ASCIIThenANSI 0100 is 4, by the way, so 1000 0100 is ++++. – mbomb007 – 2015-04-10T16:43:06.650

@mbomb007 Oh, whoops. I meant 1000 0100 becomes ++++.. – ASCIIThenANSI – 2015-04-10T17:14:18.700

1Note that you can, in fact, implement 1100 in BrainFuck. Translate 0000 to ">>", translate 0001 to "<<", prepend "+>" to the program, and translate 1100 to "<-[+<<-]+>", assuming you're targeting a BrainFuck interpreter where "<" at the start of the tape is illegal, or wraps back to the end of the tape. It's a whole lot harder otherwise. – Lymia Aluysia – 2015-04-10T22:33:26.963

@LymiaAluysia That makes sense, but it needs a compatible BF interpreter (maybe Beefit would work, since it pads the memory buffer...but it might also end up with 0 as the "random" value). – kirbyfan64sos – 2015-04-10T22:39:00.583

I've cleaned up some obsolete comments. Let me know if you want anything restored that didn't make it into the challenge (but I think everything did.) – Martin Ender – 2015-04-10T22:42:48.187

Ah... one question. Is excessive numbers also undefined? Such as in the program "11001" – Lymia Aluysia – 2015-04-10T23:43:56.047

@LymiaAluysia Yes. – kirbyfan64sos – 2015-04-11T01:10:14.410

Answers

2

CJam, 58 bytes

q{As#)},:~4/2fb{(:X8<"><+-.,[]"X={XA<{("+-"X=*}"[-]"?}?o}h

Try it online.

Explanation

q               "Read the input.";
{As#)},         "Remove any extraneous characters (not '0' or '1').";
:~              "Evaluate each character ('0' -> 0, '1' -> 1).";
4/2fb           "Split into groups of 4 (Nameless commands) and numerically
                 evaluate each group as an array of binary digits.";
{               "While command values remain:";
  (:X             "Grab the next command value.";
  8<              "If the command value is less than 8:";
  "><+-.,[]"X=    "Then: It maps directly to a BF command. Look it up.";
  {               "Else:";
    XA<             "If the command value is less than 10:";
    {("+-"X=*}      "Then: It is 8 or 9. Grab the next command value and
                     produce a string of that many copies of '+' if the former
                     command value is 8, or '-' if it is 9.";
    "[-]"?          "Else: It is 11. Produce its translation, '[-]'.";
  }?
  o               "Output the BF translation.";
}h

Runer112

Posted 2015-04-09T19:00:44.503

Reputation: 3 636

1

Perl - 343 339 305 bytes

I know CJam's already done it, but I figured I'd try a non-esoteric solution.

open(F,$ARGV[0]);%s=qw(0000 > 0001 < 0010 + 0011 - 0100 . 0101 , 0110 [ 0111 ] 1011 [-]);while(<F>){$x=0;$p='';@c=split(' ');foreach$c(@c){if($c=='1000'){for(1..oct("0b".$c[$x+1])){$p.='+'}}elsif($c=='1001'){for(1..oct("0b".$c[$x+1])){$p.='-'}}elsif(exists$s{$c}){$p.=$s{$c}}else{$p.=$c.' '};$x++}print$p}

It keeps comments, and prints it without a trailing newline.

If I've missed anything, please let me know.
Changes

  • Saved 4 bytes by deleting unnecessary characters, and fixed comments.
  • Saved 34 bytes by removing checking for 1000/1001 at the end of a line. (Credit to mbomb007)

ASCIIThenANSI

Posted 2015-04-09T19:00:44.503

Reputation: 1 935

Note that you don't have to ignore 1000 at the end of a line. "Invalid sequences (e.g. 1111) and the presence of 1000/1001 at the end of the program are undefined; you don't have to handle them." – mbomb007 – 2015-04-10T16:36:24.797

@mbomb007 Anything that's not a valid Nameless-to-BF command gets ignored (it's assuming it's a comment). Unless you mean we assume the user does not add 1000/1001 to the end of a line. – ASCIIThenANSI – 2015-04-10T16:39:07.500

Yes, we assume the user doesn't enter invalid input. (The other characters are comments, so technically valid.) – mbomb007 – 2015-04-10T16:41:32.690

@mbomb007 OK, thanks. I shaved off about 30 bytes, thanks to you! :) – ASCIIThenANSI – 2015-04-10T17:11:15.100

1Golfed Perl code is non-estoric?! ;) – kirbyfan64sos – 2015-04-10T19:28:38.253

@kirbyfan64sos Still better than most of the golfing languages out there, including BF itself. – ASCIIThenANSI – 2015-04-10T19:29:43.277

@ASCIIThenANSI BF isn't really used for golfing unless the competition is for the least number characters, and I'd prefer K to Perl if the error messages weren't such crap (then again, it usually takes me forever to fix my Perl errors, too). – kirbyfan64sos – 2015-04-10T19:32:15.853

0

Python 2, 221 216 bytes

Run it here: http://repl.it/hxJ/1

Not sure if it can be golfed more. I had to use a while (very annoyingly) instead of a list comprehension for the whole thing, since the iterator must skip an instruction if the instruction is 1000 or 1001. (By the way, the indentations are tab characters.)

import re
b='><+-.,[]'
i=re.sub('[^01]','',input())
n=[int(j,2)for j in re.findall('.'*4,i)]
k=0;o=''
while k<len(n):
    c=n[k]
    if c<8:o+=b[c]
    elif c<10:o+=n[k+1]*('+'if c<9 else'-');k+=1
    else:o+='[-]'
    k+=1
print o

mbomb007

Posted 2015-04-09T19:00:44.503

Reputation: 21 944

Do NOT edit my solution without my approval. If you want to suggest an improvement, post a comment, but this is MY solution, not yours. If you have a different one, add your own answer. Thanks. – mbomb007 – 2015-04-11T17:59:33.743