23
\$\begingroup\$

Challenge

Write a program or function that given a string, returns a valid Brainfuck program that when compiled and executed as Brainfuck, returns that string..

  1. Assume all inputs are encoded as ASCII.

  2. Assume the outputted BF program will execute in an environment with an infinite tape.

  3. Assume the pointer starts at cell 0 with every cell initialized to a value of zero.

  4. Each example below represent one possible correct output for the given input. In particular, the examples include extra newlines and spaces to help human readability. Solutions are free to format the outputted BF code in any way.

  5. The tape is doubly infinite.

  6. All cells provided by the interpreter are exactly 8-bit cells. Overflow and underflow wrap around in a predictable and sane matter.

Examples

Space string

Given the input   , your program/function could return:

+++++ +++++
+++++ +++++
+++++ +++++
++ .

Exclamation point

Given the input ! , your program/function could return:

+++++ +++++
+++++ +++++
+++++ +++++
+++
.

Two letters

Given the input hi , your program/function could return:

+++++ +++++
+++++ +++++
+++++ +++++
+++++ +++++
+++++ +++++

+++++ +++++
+++++ +++++
+++++ +++++
+++++ +++++
+++++ +++++

++++
.
+
.

This is , so the code with the smallest number of bytes wins. Good luck.

\$\endgroup\$
5
  • 11
    \$\begingroup\$ More testcases please. \$\endgroup\$
    – Leaky Nun
    Jun 26, 2016 at 8:49
  • 1
    \$\begingroup\$ What exactly are the guidelines mentioned in Revision 9? \$\endgroup\$
    – SE is dead
    Jun 26, 2016 at 23:24
  • 4
    \$\begingroup\$ I'm reopening this. I think Peter's concerns have been addressed and we have a fairly clear consensus on what counts as a duplicate, and this challenge doesn't meet those criteria. \$\endgroup\$ Jun 27, 2016 at 11:25
  • \$\begingroup\$ "Overflow and underflow wrap in a predictable and sane manner" - so 127+1 wraps to 0 and -128-1 also wraps to 0, correct? That's one possible predictable and sane manner. \$\endgroup\$
    – user253751
    Jun 29, 2016 at 5:16
  • 1
    \$\begingroup\$ @immibis Exactly. \$\endgroup\$
    – SE is dead
    Jun 29, 2016 at 14:46

36 Answers 36

62
\$\begingroup\$

Brainfuck, 55 51 bytes

,[>+++[>+++++++<-]>[<++>>+++<-]<+<[>.<-]>+++.>>-.,]

Try it online!

Example output for hi (without the linefeeds):

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++.>++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>

Explanation

This moves across the tape while writing the program. The surrounding ,[...,] is a standard input loop. For each character, we use four cells:

[... x a b c ...]

where x is the cell we write the input to.

>+++[>+++++++<-]

This part uses cell a to write a 21 into cell b via a standard multiplication of 3 and 7.

>[<++>>+++<-]

Now we use that 21 to write 42 into a and 63 into c by multiplying by 2 and 3 respectively. Then <+< moves back to cell x while turning the 42 into a 43 (the code point of +). Recap:

[... x 43 21 63 ...]

Now the main output loop:

[>.<-]

That is, while decrementing x we print one + each time.

>+++.

After we're done we reuse the + cell, by adding 3 to give ..

>>-.

Finally, we move to the 63, decrement it to 62 (>) and output that as well. The next iteration will use this cell as x.

\$\endgroup\$
1
  • 6
    \$\begingroup\$ I'd give a bounty to this if I had more rep. \$\endgroup\$
    – SE is dead
    Jun 26, 2016 at 17:15
37
\$\begingroup\$

Brainfuck, 39 33 32 31 bytes

-[-[>]<--<--],[[>.<+]>+.--.+<,]

The algorithm that places 45 on the tape is taken from Esolang's Brainfuck constants.

This answer assumes that the output program's interpreter has wrapping, bounded cells; and that , zeroes the current cell (implying that the output program is run without input). Try it online!

For a (longer) solution that works unconditionally, see my other answer.

Test run

For input Code Golf, the following output is generated.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------.,-------------------------------------------------------------------------------------------------------------------------------------------------.,------------------------------------------------------------------------------------------------------------------------------------------------------------.,-----------------------------------------------------------------------------------------------------------------------------------------------------------.,--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------.,-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------.,-------------------------------------------------------------------------------------------------------------------------------------------------.,----------------------------------------------------------------------------------------------------------------------------------------------------.,----------------------------------------------------------------------------------------------------------------------------------------------------------.,

Try it online!

How it works

We begin by putting the integer 45 (character code of -) into a cell of the tape. The following code achieves this.

-      Decrement cell 0, setting it to 255.
[      While the cell under the head in non-zero:
  [>]    Advance to the next zero cell.
  <--    Decrement the cell to its left.
  <--    Decrement the next cell to the left.
]

Before we enter the loop, the tape looks like this.

         v
000 000 255

These three cells – -2, -1, and 0 – are the only ones we'll use in this program.

In the first each iteration of the loop, the rightmost cell is, then that cell and middle cell are decremented twice, leaving the following state.

     v
000 254 252

In the next 126 iterations, the initial - decrements the middle cell, [>]< jumps to the rightmost cell, and --<-- decrements the middle and the right cell. As a result, 3 is subtracted from the middle cell (modulo 256) and 2 is subtracted from the rightmost cell.

Since 254 ÷ 3 (mod 256) = (254 + 256) ÷ 3 = 510 ÷ 3 = 170 and 252 ÷ 3 = 84, the rightmost cell is zeroed out before the middle one, leaving the following state.

     v
000 132 000

Similarly to the first iteration of the loop, the next iteration now subtracts 3 from the middle cell and 2 from the leftmost cell, placing the head on the leftmost cell.

 v
254 129 000

Subsequent iterations, as in the 126 iteration before them, subtract 3 from the leftmost cell and 2 from the rightmost cell.

Since 254 ÷ 3 (mod 256) = 170 and 129 ÷ 2 (mod 256) is undefined, this is done 170 times, leaving the following state.

 v
000 045 000

The cell under the head is zero; the loop ends.

Now we're ready to generate output.

,      Read a character from STDIN and put it the leftmost cell.
[        While the leftmost cell is non-zero:
  [        While the leftmost cell is non-zero:
    >.     Print the content of the middle cell ('-').
    <-     Increment the leftmost cell.
  ]      If the leftmost cell held n, the above will print 256 - n minus signs
         which, when executed, will put n in cell 0 of the output program.
  >      Increment the middle cell, setting it to 46 ('.').
  .      Print its content ('.').
  --     Decrement the middle cell twice, setting it to 44 (',').
  .      Print its content (',').
         When executed, since the output program receives no input, the above
         will zero cell 0 of the output program.
  +      Increment the second cell, setting it back to 45 ('-').
  <,     Go back to the leftmost cell and read another character from STDIN.
]      Once EOF is reached, this will put 0 in the leftmost cell, ending the loop.
\$\endgroup\$
2
  • \$\begingroup\$ Why does the resulting BF not translate back to the input string for me? This is the interpreter I'm using, which has worked for the other answers. \$\endgroup\$
    – Insane
    Jun 27, 2016 at 7:17
  • 2
    \$\begingroup\$ That interpreter has a lot of settings. For the 32 byte version, you'd need dynamic memory and end of input: \0. \$\endgroup\$
    – Dennis
    Jun 27, 2016 at 7:22
19
\$\begingroup\$

Jelly, 8 bytes

O”+ẋp“.>

Try it online!

Sample run

For input hi, this program prints

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++.+++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++>

(without the linefeeds) which, in turn, prints hi.

How it works

O”+ẋp“.>  Main link. Argument: s (string)

O         Ordinal; convert each character in s into its code point.
 ”+       Yield the character '+'.
   ẋ      Repeat '+' k times, for each k in the code points.
     “.>  Yield the string ".>".
    p     Take the Cartesian product of both results.
\$\endgroup\$
5
  • \$\begingroup\$ Yours don't work on limited memory, mine does. \$\endgroup\$
    – Leaky Nun
    Jun 26, 2016 at 16:22
  • 5
    \$\begingroup\$ Not really. We both store the entire output in memory before printing. For BF interpreters with a large enough tape, that will become an issue long before the tape does. \$\endgroup\$
    – Dennis
    Jun 26, 2016 at 16:34
  • \$\begingroup\$ Why doesn't .> appear in the output? \$\endgroup\$
    – cat
    Jun 27, 2016 at 18:26
  • 2
    \$\begingroup\$ @cat Because Cartesian product (p) is shorter than append to each (;€). These ouput programs double the cell after printing and before switching. Since we never revisit the cell, it doesn't affect the output. \$\endgroup\$
    – Dennis
    Jun 27, 2016 at 19:06
  • \$\begingroup\$ @Dennis ahh, interesting. \$\endgroup\$
    – cat
    Jun 27, 2016 at 19:23
12
\$\begingroup\$

Brainfuck, 3513 43 bytes

++[>+<------],[[>.>+<<-]>+++.->[<.>-]<--<,]

This answer makes no assumptions about the interpreter of the output program. Try it online!

For a shorter solution (which works only with some interpreters), see my other answer.

Test run

For input Code Golf, the following output is generated.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.-------------------------------------------------------------------+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.---------------------------------------------------------------------------------------------------------------++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.----------------------------------------------------------------------------------------------------+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.-----------------------------------------------------------------------------------------------------++++++++++++++++++++++++++++++++.--------------------------------+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.-----------------------------------------------------------------------+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.---------------------------------------------------------------------------------------------------------------++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.------------------------------------------------------------------------------------------------------------++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.------------------------------------------------------------------------------------------------------+++++++++++++++++++++++++++++++++.---------------------------------

Try it online!

How it works

We begin by putting the integer 43 (character code of +) in the second cell of the tape. The following code achieves this.

++         Increment the first cell twice, setting it to 2.
[          While the first cell in non-zero:
  >+         Increment the second cell.
  <------    Decrement the first cell six times.
]

This essentially performs the modular division 2 ÷ 6 (mod 256). Since (2 + 256) ÷ 6 = 258 ÷ 6 = 43, the result is 43, as intended.

Now we're ready to generate output.

,      Read a character from STDIN and put it the first cell.
[        While the first cell is non-zero:
  [        While the first cell is non-zero:
    >.     Print the content of the second cell ('+').
    >+     Increment the third cell.
    <<-    Decrement the first cell.
  ]      If the first cell held n, the above prints n plus signs
         and puts n in the third cell.
  >+++   Add three to the second cell, setting it to 46 ('.').
  .      Print its content ('.').
  -      Decrement, setting it to 45 ('-').
  >      Advance to the third cell.
  [      While the third cell is non-zero:
    <.     Print the content of the second cell ('-').
    >-     Decrement the third cell.
  ]      If the first cell held n, the above prints n minus signs,
         thus negating the plus signs and zeroing the cell of the output program.
  <--    Subtract 2 from the second cell, setting it back to 43.
  <,     Go back to the first cell and read another character from STDIN.
]      Once EOF is reached, ',' will put 0 in the first cell, ending the loop.
\$\endgroup\$
2
  • \$\begingroup\$ Aw, man! You can't break the crossed-out-44-is-44 meme, come on! Anyway your attempt to defeat it failed miserably because it doesn't look struck out, it looks like there is some dirt on my screen (PHP, perhaps?) :P \$\endgroup\$
    – cat
    Jun 28, 2016 at 18:39
  • 2
    \$\begingroup\$ Anything to avoid that comment... \$\endgroup\$
    – Dennis
    Jun 29, 2016 at 0:00
5
\$\begingroup\$

Pyth - 11 bytes

sm+*\+Cd".>

Try it online here.

\$\endgroup\$
4
\$\begingroup\$

05AB1E, 12 11 bytes

vyÇ`'+ׄ.>J

Explained

v             # for each char in input string
 yÇ`          # convert to its ascii value
    '+×       # push the char '+' that many times
       „.>J   # push string ".>" and join with the plus signs
              # implicitly print combined string

Try it online

Saved 1 byte thanks to @Adnan

\$\endgroup\$
2
  • \$\begingroup\$ '+× instead of F'+} saves a byte. \$\endgroup\$
    – Adnan
    Jun 27, 2016 at 18:06
  • 1
    \$\begingroup\$ @Adnan: Thanks! I was looking for a "repeat" command. \$\endgroup\$
    – Emigna
    Jun 27, 2016 at 18:48
4
\$\begingroup\$

Java, 98 bytes

class a{String A(char[]b){String z="";for(char B:b){for(int c=B;c-->0;)z+="+";z+=".>";}return z;}}

Strings are nothing more than immutable char[]s with a bunch of utility methods, so let's use the array!

Ungolfed:

class a {
    void A(char[] b) {
        for (char B : b) {
            for (int c = B; c-- > 0;)
                 System.out.print('+');
            System.out.print(".>");
        }
    }
}

Equivalent standalone program that is 138 bytes long:

interface a{static void main(String[]A){for(char b:A[0].toCharArray()){for(int B=b;B-->0;)System.out.print('+');System.out.print(".>");}}}

Bonus:

interface a{static void main(String[]A){for(char b:new java.util.Scanner(new java.io.File(A[0])).useDelimiter("\\Z").next().toCharArray()){for(int B=b;B>0;B--)System.out.print('+');System.out.print(".>");}}}

This 207-byte app actually encodes a file as a BF program, just as said in the title.

\$\endgroup\$
2
  • 3
    \$\begingroup\$ Is it just me or does the way the ungolfed program is indented look awesome? \$\endgroup\$
    – SE is dead
    Jun 26, 2016 at 23:10
  • \$\begingroup\$ Realized right before I posted that my answer is basically a golfed down version of yours. \$\endgroup\$
    – Insane
    Jun 27, 2016 at 7:59
3
\$\begingroup\$

Brainfuck, 29 bytes

,[[+>+[---------.]<]--[--.],]

Try it online!

Explanation:

,[                  loop over all characters on input
  [+                output number of minuses based on input
    >+[---------.]< print characters including -
  ]
  --[--.]           print all even characters in reverse equal to .,
,]

This solution expects classic 8-bit wrapping interpreter and uses the fact that other characters than +-,.<>[] are ignored by brainfuck interpreter. It also expects that generated program will be run with no input and thus receives null bytes as input - reading of input is used to clear the cell.

Statement generating - actually generates following string: øïæÝÔ˹°§zqh_VMD;2) üóêáØÏƽ´«¢~ulcZQH?6-$ , where the only interpretable character is -.

Statement generating ., actually generates üúøöôòðîìêèæäâàÞÜÚØÖÔÒÐÎÌÊÈÆÄÂÀ¾¼º¸¶´²°®¬ª¨¦¤¢ ~|zxvtrpnljhfdb`^\ZXVTRPNLJHFDB@><:86420.,*(&$"  where following characters are interpreted ><.,. The >< moves pointer right and then left, so it actually doesn't do anything.

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

Vitsy, 19 17 bytes

I\[&'>.+'i1-\Du]Z

I                     Get the length of the input stack.
 \[            ]      Pop n, repeat this block of code n times.
   &                  Push a new stack and move to it.
    '>.+'             Push the string '+.>' to the stack.
         i            Pop an item from the input stack and push it to the current
                      program stack.
          1-          Subtract one from the top program stack item.
            \D        Duplicate the '+' in the stack that many times.
              u       Merge the current program stack with the previous.
                Z     Output the entire current stack as a string.

Note that this answer is one of the few times that I've ever used I and u. :D

Try it online!

\$\endgroup\$
2
\$\begingroup\$

O, 13 bytes

i{'+n#*".>"}d

Explanation:

i              Read standard input into a string and push it onto the stack.
 {         }d  For each character in the string...
  '+           Push "+".
    n#         Convert the character (n) to its ASCII code.
      *        Multiply the "+" by the character code to get the number of +'s needed.
       ".>"    Push the string ".>".
               In O, the stack is printed after execution, so this prints out the result.
\$\endgroup\$
2
\$\begingroup\$

K6, 16 bytes

,/{|">.",x#"+"}'

Usage

,/{|">.",x#"+"}'"some string"

Explanation

  {           }'  For each character in the string...
         x#"+"    Repeat "+" as many times as the character's ASCII code.
        ,         Combine that with...
    ">."          The code to print it and move on.
   |              But we put the string together backwards...so now it gets reversed.
,/                Combine all the substrings into one BIG string.
\$\endgroup\$
2
  • \$\begingroup\$ Explanation plz :D \$\endgroup\$ Jun 26, 2016 at 20:07
  • \$\begingroup\$ @VTCAKAVSMoACE Done! :) \$\endgroup\$ Jun 26, 2016 at 20:14
2
\$\begingroup\$

Python 3, 43 bytes

lambda s:''.join('+'*ord(c)+'.>'for c in s)

The Python puts a number of pluses equivalent to the ASCII code of each character, followed by .> to print and move to the next cell. The brainfuck increments up to the correct value, prints, and moves on to the next cell.

Output for hi (with newlines for clarity):

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++.>++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>

That program's output:

hi
\$\endgroup\$
2
\$\begingroup\$

Perl, 25 bytes

s/./"+"x ord($&).".>"/eg

Usage

echo -n hi | perl -pe 's/./"+"x ord($&).".>"/eg'

Explanation

Uses a regular expression replace operation to replace every character in every line given on standard input with a number of + calculated from the ordinal value of that character, then outputs .> to print and advance to the next character.

Uses the perl -p flag to automatically read the input and print the result, adding 1 extra to the bytecount.

\$\endgroup\$
2
\$\begingroup\$

Java, 91 bytes

String b(char[] f){String k="";for(char b:f){for(int u=b;u>0;u--)k+="+";k+=".>";}return k;}

Props to dorukayhan for beating me to it :)

\$\endgroup\$
4
  • \$\begingroup\$ You can't just remove the boilerplate and change all the names of the variables and then claim that as a new answer. \$\endgroup\$
    – Leaky Nun
    Jul 18, 2016 at 8:42
  • \$\begingroup\$ @LeakyNun I didn't, but I could if I wanted to. \$\endgroup\$
    – Insane
    Jul 18, 2016 at 8:43
  • \$\begingroup\$ How is this answer different from the answer you linked to? \$\endgroup\$
    – Leaky Nun
    Jul 18, 2016 at 9:03
  • \$\begingroup\$ @LeakyNun Downvote and move on \$\endgroup\$
    – Insane
    Jul 18, 2016 at 9:04
2
\$\begingroup\$

C, 72 64 60 bytes

main(c){for(;c=~getchar();)for(;printf(~c++?"+":".>")^2;);}

Ungolfed version:

main( c )
{
    for ( ; c = ~getchar( ); )
        for ( ; printf( ~c++ ? "+" : ".>" ) ^ 2; );
}

Compile and test with:
gcc -o bfcat bfcatgolf.c && cat 1.txt | ./bfcat > o.txt && beef o.txt

Results

\$\endgroup\$
2
  • \$\begingroup\$ Why is c the bitwise inverse of getchar, especially if you just invert the inversion again? \$\endgroup\$
    – cat
    Jun 29, 2016 at 2:41
  • \$\begingroup\$ @cat c = ~getchar( ) evaluates to 0 on EOF. c = ~getchar( ) and ~c++ are simply shorter than ~( c = getchar( ) ) and c-- \$\endgroup\$
    – Jacajack
    Jun 29, 2016 at 8:46
2
\$\begingroup\$

CJam, 12 bytes

Converts each character to its ASCII value, and increments the current cell by that number of times before printing it. Since we have infinite tape we can just move to the right after processing each character.

q{i'+*'.'>}%

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Lua, 67 66 61 Bytes

Simply iterate over each characters in the argument, and print a line for each one with n +s followed by .> where n is the value of this character in the ASCII Table.

Uses gmatch as @LeakyNun advised in the comment for saving 1 Bytes over the the gsub solution

for c in(...):gmatch"."do print(("+"):rep(c:byte())..".>")end

Old solution using gsub

(...):gsub(".",function(c)print(c.rep("+",c:byte())..".>")end)

Old 67

(...):gsub(".",function(c)print(string.rep("+",c:byte())..".>")end)

To run it, just save it as a file (golf.lua for instance) and run it with lua golf.lua "hi". For hi, it should output

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>
\$\endgroup\$
7
  • \$\begingroup\$ How do I use this? Just pasting it in the REPL gives attempt to index a nil value, and f = ... gives the same, and function f ... end gives unexpected symbol near ':' \$\endgroup\$
    – cat
    Jun 27, 2016 at 22:09
  • \$\begingroup\$ @cat Just save it in a file and run it as lua file.lua "argument", I will update the post to give instructions. \$\endgroup\$
    – Katenkyo
    Jun 28, 2016 at 6:33
  • \$\begingroup\$ How does that even work? is ... an identifier with argv? \$\endgroup\$
    – cat
    Jun 28, 2016 at 13:57
  • 1
    \$\begingroup\$ @cat ... contains the values in the table arg unpacked. Which means it will always correspond to arg[1] unless you use it in a function call as the last parameter, then it will expend. \$\endgroup\$
    – Katenkyo
    Jun 28, 2016 at 14:15
  • \$\begingroup\$ n=...for n:gmatch"."do print(("+"):rep(c:byte())..".>")end for 48 bytes \$\endgroup\$
    – Leaky Nun
    Jul 18, 2016 at 8:39
2
\$\begingroup\$

Sesos, 12 bytes

Hexdump:

0000000: 28cbf6 02e83d 655bae 243901                       (....=e[.$9.

Size   : 12 byte(s)

Try it online!

Assembler

add 43,fwd 1,get
jmp
  jmp,sub 1,rwd 1,put,fwd 1,jnz
  add 46,put,add 16,put
  get
\$\endgroup\$
2
\$\begingroup\$

brainfuck, 27 bytes

,[[>+[++++.+++]<-]--[.--],]

Try it online! Try result

Optimized from Jiří's solution

JavaScript (V8), 49 bytes

x=>[...x].map(c=>'+'.repeat(c.charCodeAt())+.1)+0

Try it online!

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

J, 28 bytes

[:;[:('.>',~'+'#~])"0[:]3&u:

Simple enough. 3&u: converts chars to char codes. The rest is just repeat '+' that number of times, then concatenating with .> at the end of each line, and ; flattens the result.

Some results

   bf =: [:;[:('>.',~'+'#~])"0[:]3&u:
   bf 'hi'
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>.
   bf ' !'
++++++++++++++++++++++++++++++++>. +++++++++++++++++++++++++++++++++>.
   bf ' ~'
++++++++++++++++++++++++++++++++>.
                 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>.
\$\endgroup\$
1
\$\begingroup\$

Pyke, 11 bytes

F.o\+*".>"+

Try it here!

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

Actually, 13 bytes

O`'+*".>"@`MΣ

Try it online!

The strategy used here is the same as in many of the other solutions - for each character, output enough +s to increment a zero-initialized cell to the proper ASCII ordinal, output it with ., and move to the next cell with >.

Explanation:

O`'+*".>"@`MΣ
O              list of ordinals (technically this is Unicode code points, but code points 0-127 are the same for Unicode and ASCII)
 `'+*".>"@`M   for each ordinal:
  '+*            push a string containing that many +s
     ".>"@       push ".>" and swap (putting it before the +s)
            Σ  concatenate all the strings (if "[", "]", and "," weren't meaningful characters in BF, this technically wouldn't be necessary)
\$\endgroup\$
1
\$\begingroup\$

Mouse-2002, 27 bytes

(?'l:l.^(l.^"+"l.1-l:)".>")

This works in theory and according to the language's documentation, but the reference implementation of Mouse's interpreter seems to have a bug where string input appends a ', so for a this outputs

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>+++++++++++++++++++++++++++++++++++++++.>

Which in turn outputs a'. That may or may not be okay, so here's a 39 byte long one which doesn't output ' ever and thus is likely more invalid.

(?'l:l.39=l.0=+0=^(l.0>^"+"l.1-l:)".>")

Which gives right output in the reference impl. as long as there are no 's :)

Explained:

(              ~ while (true) {
  ?' l:        ~   l = getchar() 
  l. ^         ~   if (! (l) ) { break }
  (            ~   while (true) {
    l. ^       ~     if (! (l) ) { break }
    "+"        ~     puts("+")
    l. 1 - l:  ~     l-- // l = l - 1
  )            ~   }
  ".>"         ~   puts(".>")
)              ~ }
\$\endgroup\$
1
\$\begingroup\$

Factor, 58 bytes

[ [ [ 43 ] ""replicate-as ".>"append ] { } map-as ""join ]

Works like:

[ 
  [ 
    [ 43 ] "" replicate-as  ! ``+'' * code point, clone-like a string ""
    ".>" append             ! append ".>"
  ] 
  { } map-as                ! for each char in string and clone-like an array { }
  "" join                   ! join array of str into str by ""
]

Since Factor comes with a Brainfuck interpreter, it's simple to test.

bfcat.factor

USING: sequences ;
IN: bfcat

: string>brainfuck ( s -- bf )
  [ [ 43 ] "" replicate-as ".>" append ]
  { } map-as "" join ;

bfcat-tests.factor

USING: tools.test bfcat brainfuck ;
IN: bfcat.tests

{ "a"  } [ "a"  string>brainfuck get-brainfuck ] unit-test
{ "ab" } [ "ab" string>brainfuck get-brainfuck ] unit-test
{ "+++++++++++++" } [ "+++++++++++++" string>brainfuck get-brainfuck ] unit-test
{ "Code Golf" } [ "Code Golf" string>brainfuck get-brainfuck ] unit-test

output

Unit Test: { { "a" } [ "a" string>brainfuck get-brainfuck ] }
Unit Test: { { "ab" } [ "ab" string>brainfuck get-brainfuck ] }
Unit Test: {
    { "+++++++++++++" }
    [ "+++++++++++++" string>brainfuck get-brainfuck ]
}
Unit Test: {
    { "Code Golf" }
    [ "Code Golf" string>brainfuck get-brainfuck ]
}

Yay! they all pass.

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

Ruby, 40 38 bytes

gets.chop.each_byte{|o|puts"+"*o+".>"}
\$\endgroup\$
2
  • \$\begingroup\$ I don't know ruby but I do know you can use puts instead of print, as the format of the output is not significant as long as it is valid brainfuck and brainfuck does not care about other characters \$\endgroup\$
    – cat
    Jun 27, 2016 at 19:24
  • \$\begingroup\$ @cat oh I didn't know that bf ignores other characters, thanks! \$\endgroup\$
    – CocoaBean
    Jun 28, 2016 at 18:30
1
\$\begingroup\$

Sidef, 38 bytes

Hey, the same length as Ruby! just that Sidef isn't Ruby :D

read().bytes.each{|c|say"+"*c;say".>"}

Read some chars, then for each byte do that thing.

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

GNU Bash, 100 85 bytes

while IFS= read -rn1 c;do printf '+%.0s' $(seq 1 $(printf %d \'$c));echo '.>';done<$1

Thanks @cat for saving me 15 bytes!

Postramble

  1. Assumes input string is represented as-is in a file passed as first argument.
  2. Usage: bash bfcat.sh <path to file containing string>
  3. Usage (with named pipe): bash bfcat.sh <(echo -n '<string>')

Ungolfed

while IFS= read -r -n1 c # Read file byte by byte [1]
do
    n=$(printf "%d" \'"$c") # `ord` of a char in bash [2]
    printf '+%.0s' $(seq 1 $n) # emit character $n times [3]
    echo '.>' # Emit output and shift command for bf. I love infinite memory.
done <"$1"

References in Ungolfed version

  1. Read file byte by byte

  2. ord of a char in bash

  3. emit character $n times

\$\endgroup\$
3
  • 1
    \$\begingroup\$ I've improved some of the formatting and stuff in your answer, and removed redundant information from the links. Feel free to undo it if you don't like it. Also, it's GNU Bash, not GNU/Bash like GNU/Linux. :) \$\endgroup\$
    – cat
    Jun 29, 2016 at 2:53
  • 1
    \$\begingroup\$ Golfing tips (I'm no bash golfer): read -rn1, get rid of spaces after ;, get rid of the space in done <"$1" to save a total of 9 bytes \$\endgroup\$
    – cat
    Jun 29, 2016 at 2:56
  • 1
    \$\begingroup\$ @cat It looks awesome! I really need to get in the habit of edit->preview->edit->... \$\endgroup\$
    – Yeow_Meng
    Jun 29, 2016 at 3:04
1
\$\begingroup\$

ES6, 119 115 bytes

f=s=>{a='';for(i in[...s]){b=s[c='charCodeAt'](i)-(s[c](i-1)|0);a+=(b>0?'+'.repeat(b):'-'.repeat(-b))+'.'}return a}

Saved 4 bytes, thanks to @Leibrug

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can assign charCodeAt to some var (let's say c) and use like that: s[c](i) to shorten by 1 byte, and also remove some characters (i found 3: space before [...s], replace logical OR with bitwise one, and semicolon before return). \$\endgroup\$
    – Leibrug
    Jul 13, 2016 at 6:48
1
\$\begingroup\$

Haskell 50 Bytes

f[]=[]
f(x:y)=replicate(fromEnum x)'+'++".>"++f y
\$\endgroup\$
1
\$\begingroup\$

><>, 39 41 bytes

0i:@:0(?;\~~o!
v?:+"Ā"-$/'.'~
/.13-1o'+'

Explanation

Add 256 to each char code, then print that many +, then .

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.