Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Write the shortest program in your favourite language to interpret a Brainfuck program. The program is read from a file. Input and output are standard input and standard output.

  1. Cell size: 8bit unsigned. Overflow is undefined.
  2. Array size: 30000 bytes (not circled)
  3. Bad commands are not part of the input
  4. Comments begin with # and extend to the end of line Comments are everything not in +-.,[]<>
  5. no EOF symbol

A very good test can be found here. It reads a number and then prints the prime numbers up to that number.

$ python2 bf.py PRIME.BF 
Primes up to: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 
share|improve this question
You should clarify about 1) size of memory 2) is memory circled 4) maybe any other details –  Nakilon Jan 28 '11 at 1:37
When you say bad commands are not part of the input, you mean that all programs will behave in the given guidelines? Or is validation on where the memory pointer is and what values are in memory needed? Also, is there a limit to the input file size? –  Juan Jan 29 '11 at 2:54
Another question: Why the unusual comment syntax? Usually everything that isn't ,.-+[]<> is a comment in brainfuck. (I'm asking because it makes my implementation quite a bit longer than it needs to be) –  sepp2k Jan 30 '11 at 15:33
I wonder if there should be two categories: Those programs that use eval (or shell out to compile) -- and those that don't. –  MtnViewMark Feb 15 '11 at 7:52
I'd love to see someone answer this in brainfuck. –  Hannesh Mar 14 '11 at 19:15

32 Answers 32

up vote 28 down vote accepted

Perl, 120 138

%c=qw(> $p++ < $p-- + D++ - D-- [ while(D){ ] } . print+chrD , D=ord(getc));

This runs hello.bf and primes.bf flawlessly:

$ perl bf.pl hello.bf
Hello World!
$ perl bf.pl prime.bf
Primes up to: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

Initialization: The opcode to Perl translation table is stored in %c. The readable form looks like this:

  '>' => '$p++',
  '<' => '$p--',
  '+' => '$b[$p]++',
  '-' => '$b[$p]--',
  '[' => 'while($b[$p]){',
  ']' => '}',
  '.' => 'print chr$b[$p]',
  ',' => '$b[$p]=ord(getc)',

Step 1: Slurp program input to $_ and transform it to Perl code using the translation table. Comments are automatically stripped (replaced with undef) in this step.

Step 2: Uncompress all $b[$p] occurrences

Step 3: Launch the program using eval.

share|improve this answer
Just use Perl's qw syntax to define %c directly -- good for 7 fewer chars (you'll have to say print+chr$b[$p] and ord(getc), though) –  mob Sep 11 '12 at 23:36
I count 18 saved… thanks! (updating in a minute) –  J B Sep 12 '12 at 8:19
The %c table also has code and should be counting characteres too. –  olivecoder Sep 19 '12 at 3:12
@olivecoder What on earth are you talking about? –  J B Sep 19 '12 at 7:12
I really dont know! :) please forgive me I've not paid attention for your code. –  olivecoder Sep 19 '12 at 12:31

16 bit 8086 machine code: 168 bytes

Here's the base64 encoded version, convert and save as 'bf.com' and run from Windows command prompt: 'bf progname'



Here's some assembler (A86 style) to create the executable (I had to reverse engineer this as I'd misplaced the original source!)

    add dh,10h                              
    push dx                                 
    add dh,10h                              
    push dx                                 
    mov bl,80h                              
    lea dx,[bx+2]                         
    add bl,[bx]                            
    mov [bx+1],al                         
    mov ah,3dh                              
    int 21h                                 
    pop ds                                 
    pop es                                 
    jb ret                               
    mov bx,ax                              
    mov ah,3fh                              
    mov cx,di                              
    xor dx,dx                              
    int 21h                                 
    jb ret                               
    mov bx,ax                              
    xor ax,ax                              
    repz stosw                                     
    xor di,di                              
    xor si,si                              
    inc ch                                 
    cmp si,bx                              
    jnb ret                               
    mov bp,8                            
    push program_loop
    dec bp                                 
    js ret
    cmp al,[bp+symbols]
    jnz symbol_search
    mov cl,[bp+instructions]
    jmp cx                                 
    inc di                                 
    inc b es:[di]                      
    dec b es:[di]                      
    mov ah,2                              
    mov dl,es:[di]                            
    int 21h                                 
    mov ah,1                              
    int 21h                                 
    dec di                                 
    cmp es:[di],dh                            
    jnz ret                               
    xor bp,bp
l1: cmp si,bx                              
    jnb ret
    cmp al,'['                              
    jnz l2
    inc bp
l2: cmp al,']'                              
    jnz l1
    dec bp                                 
    jns l1
    cmp es:[di],dh                            
    jz  ret
    xor bp,bp
l3: dec si                                 
    jz  ret
    mov al,[si-1]                         
    cmp al,']'
    jnz l4
    inc bp  
l4: cmp al,'['                              
    jnz l3
    dec bp                                 
    jns l3
    db '><+-.,[]'
    db forward and 255
    db backward and 255
    db increment and 255
    db decrement and 255
    db output and 255
    db input and 255
    db jumpforwardifzero and 255
    db jumpbackwardifnotzero and 255
share|improve this answer
I've added a source code version of the program. I've just noticed that non-bf characters cause the program to exit rather than be ignored. Easy to fix that and I'll leave it as an exercise for people to do that themselves. –  Skizz Aug 14 '12 at 13:18
I remember I got the Linux ELF version 166 bytes, 10 years ago, here muppetlabs.com/~breadbox/software/tiny –  Emmanuel Jul 28 at 17:34

Ruby 1.8.7, 188 185 149 147 characters

eval"a=[i=0]*3e4;"+$<.bytes.map{|b|{?.,"putc a[i]",?,,"a[i]=getc",?[,"while a[i]>0",?],"end",?<,"i-=1",?>,"i+=1",?+,"a[i]+=1",?-,"a[i]-=1"}[b]}*";"

Somewhat readable version:

code = "a = [0] * 3e4; i = 0;"
more_code ARGF.bytes.map {|b|
  replacements = {
    ?. => "putc a[i]",
    ?, => "a[i] = getc",
    ?[ => "while a[i] > 0 do",
    ?] => "end",
    ?< => "i -= 1",
    ?> => "i += 1",
    ?+ =>"a[i]+=1",
    ?- =>"a[i]-=1"
eval code+more_code

As you see I shamelessly stole your idea of translating to the host language and then using eval to run it.

share|improve this answer
You can shave off a byte byte comparing to zero >0 rather than testing equality: !=0. The specs say unsigned, and overflow is undefined. –  Charlie Somerville Feb 6 '11 at 5:32
3e4 will also work as opposed to 30000 –  Charlie Somerville Feb 6 '11 at 5:36
@Charlie: Thanks. Though to be fair it didn't say "unsigned" when I wrote the code. I honestly didn't know that you could write 3e4 though. That's a very good point and good to know. –  sepp2k Feb 6 '11 at 5:40
File.read($*.pop).bytes -> $<.bytes should work too –  user300 Feb 12 '11 at 22:31
Ruby 1.8.7 has an even shorter syntax to build a literal hash: {?a,"foo"}, which is equivalent to {?a=>"foo"}. And testing here shows that you actually can replace File.read($*.pop).bytes with $< without any problems. Also inlining everything to something like eval"a[0]..."+$<.bytes.map{?.,"putc a[i]",...}*";" shortens the solution by another few characters. –  Ventero Feb 14 '11 at 15:58

Python (no eval), 317 char

from sys import*
def f(u,c,k):
  while b*c[c[0]]and j<1:f(u,c,k+1);c[1]+=1
share|improve this answer
+1 for the f(u,c,k) –  Joel Cornett Aug 4 '12 at 21:48

Python 275 248 255

I decided to give it a try.

import sys
for e in open(sys.argv[1]).read():
 t+=' '*i+['i+=1','i-=1','b[i]+=1','b[i]-=1','sys.stdout.write(chr(b[i]))','b[i]=ord(sys.stdin.read(1))','while b[i]:','pass','']['><+-.,['.find(e)]+'\n'
 i+=(92-ord(e))*(e in'][')
exec t 
share|improve this answer
Neat, you are generating python source code using brainfuck. –  user11 Jan 30 '11 at 2:00
You may strip 1 char, "import sys as s" and replace "sys" to "s" in the rest –  YOU Feb 6 '11 at 6:52
Note that this is actually 247 chars. (See the nasty space after exec t?). If you use S.Mark's tip and also make the whole for cycle into one line, you can shrink this to 243 chars. –  Oleh Prypin Apr 4 '11 at 15:18
This fails on any input containing [], a valid though trivial bf program. I've suggested an edit which fixes this, but increases the character count. To further reduce the character count, you can from sys import *, and use 'i+=1,...'.split(',') instead of ['i+=1',...]. –  boothby Jul 5 '11 at 20:19
I wrote a 227 character version of this in python myself, and there are a few tricks you could use to shorten your code. Rather than storing the number of indents in i, and incrementing/decrementing i, you can store the indent itself, which takes exactly as many characters to update (i=i[e==']':]+' '[e!='[':]), and saves you from doing i*' ', and lets you do i=t=''. Rather than storing '' as the last item in the array, you can keep pass as the last one, which translates any non-operation into pass, which works fine. Everything else I did has been suggested already. –  Strigoides Oct 20 '12 at 5:42

Binary Lambda Calculus 112

The program shown in the hex dump below

00000000  44 51 a1 01 84 55 d5 02  b7 70 30 22 ff 32 f0 00  |DQ...U...p0".2..|
00000010  bf f9 85 7f 5e e1 6f 95  7f 7d ee c0 e5 54 68 00  |....^.o..}...Th.|
00000020  58 55 fd fb e0 45 57 fd  eb fb f0 b6 f0 2f d6 07  |XU...EW....../..|
00000030  e1 6f 73 d7 f1 14 bc c0  0b ff 2e 1f a1 6f 66 17  |.os..........of.|
00000040  e8 5b ef 2f cf ff 13 ff  e1 ca 34 20 0a c8 d0 0b  |.[./......4 ....|
00000050  99 ee 1f e5 ff 7f 5a 6a  1f ff 0f ff 87 9d 04 d0  |......Zj........|
00000060  ab 00 05 db 23 40 b7 3b  28 cc c0 b0 6c 0e 74 10  |....#@.;(...l.t.|

expects its input to consist of a Brainfuck program (looking only at bits 0,1,4 to distinguish among ,-.+<>][ ) followed by a ], followed by the input for the Brainfuck program.

Save the above hex dump with xxd -r > bf.Blc

Grab a blc interpreter from http://www.cwi.nl/~tromp/cl/uni.c

cc -O2 -DM=0x100000 -m32 -std=c99 uni.c -o uni
echo -n "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.]" > hw.bf
cat bf.Blc hw.bf | ./uni

Hello World!

share|improve this answer

Haskell, 457 413 characters

import IO
import System
'+'#(c,m)=z(succ c,m)
'-'#(c,m)=z(pred c,m)
'.'#t@(c,_)=putChar c>>hFlush stdout>>z t
_#t=z t
_%t@('\0',_)=z t
i%t=i t>>=(i%)
b('[':r)=k$b r
b(c:r)=f(c#)$b r
f j(i,r)=(\t->j t>>=i,r)
k(i,r)=f(i%)$b r
main=getArgs>>=readFile.head>>=($('\0',("",repeat '\0'))).fst.b

This code "compiles" the BF program into an IO action of the form State -> IO State the state is a zipper on an infinite string.

Sad that I had to expend 29 characters to turn buffering off. Without those, it works, but you don't see the prompts before you have to type input. The compiler itself (b, f, and k) is just 99 characters, the runtime (# and %) is 216. The driver w/initial state another 32.

>ghc -O3 --make BF.hs 
[1 of 1] Compiling Main             ( BF.hs, BF.o )
Linking BF ...

Hello World!

Primes up to: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 

update 2011-02-15: Incorporated J B's suggestions, did a little renaming, and tightened up main

share|improve this answer
You should be able to get the buffering from just IO, and the arguments from just System (-19). The buffering issue bothers me as well, as the spec doesn't really mention it and the top-voted answer doesn't even do I/O. If you must keep it, it's probably shorter to hFlush after each write than change the global buffering mode (-34+15). –  J B Feb 15 '11 at 10:49

C 284 362 (From a file)

#include <stdio.h>
char b[30000],z[9999],*p=b,c,*a,i;f(char*r,int s){while(c=*a++){if(!s){(c-62)?(c-60)?(c-43)?(c-45)?(c-46)?(c-44)?0:(*p=getchar()):putchar(*p):--*p:++*p:--p:++p;if(c==91)f(a,!*p);else if(c==93){if(!*p)return;else a=r;}}else{if(c==93){--s;if(!*p&&!s)return;}else if(c==91){s++;}}}}main(int c,char**v){fread(z,1,9999,fopen(*++v,"r"));a=z;f(0,0);}


Primes up to: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
Press any key to continue . . .

Compiled and ran successfully VS2008

Original solution failed to recognize loops that were initially set to zero. Still some room to golf. But finally solves the Prime Number program.


#include <stdio.h>
char b[30000],z[9999],*p=b,c,*a,i;
f(char*r,int s)
            else if(c==93){if(!*p)return;else a=r;}
            else if(c==91)

main(int c,char**v){


Hello World


share|improve this answer
Are you checking the same pointer (l) every time you loop? I think you are supposed to check the current location of the head (p). –  Alexandru Jan 30 '11 at 19:51
I pass the pointer to the buffer and the pointer to the stream. It checks at the end of the loop to see if the pointer l in the buffer has reached zero and breaks else it resets the stream back to the original loop [. This is necessary for nested [ loops. –  snmcdonald Jan 30 '11 at 20:00
Yeah. I thought so. You should not check the value at pointer at first enter in the loop, but the value at the current pointer. Check the test in the question. Your program hangs. –  Alexandru Jan 30 '11 at 20:10
You can replace break;else by return;. –  Alexandru Jan 30 '11 at 20:56
I think you can replace (c==62)?a:b with (c-62)?b:a. –  Alexandru Jan 30 '11 at 22:01

PHP 5.4, 296 294 273 263 261 209 191 183 178 166 characters:

I gave it a shot without using eval, but I eventually had to use it

<?$b=0;eval(strtr(`cat $argv[1]`,["]"=>'}',"["=>'while($$b){',"."=>'echo chr($$b);',","=>'$$b=fgetc(STDIN);',"+"=>'$$b++;',"-"=>'$$b--;',">"=>'$b++;',"<"=>'$b--;']));

All commands are working. This heavily abuses variable variables, and spews warnings. However, if one changes their php.ini to squelch warnings (or pipes stderr to /dev/null), this works great.

Verification (It's the "Hello World!" example from Wikipedia): http://codepad.viper-7.com/O9lYjl

Ungolfed, 367 365 335 296 267 characters:

$a[] = $b = 0;
$p = implode("",file($argv[1])); // Shorter than file_get_contents by one char
$m = array("]" => '}', "[" => 'while($a[$b]){',"." => 'echo chr($a[$b]);', "," => '$a[$b]=fgetc(STDIN);', "+" => '$a[$b]++;', "-" => '$a[$b]--;', ">" => '$b++;', "<" => '$b--;');
$p = strtr($p,$m);

This should be run via the command line: php bf.php hello.bf

share|improve this answer
Could anyone please accept my edit or make this answer a CW? –  Karel Petranek Feb 16 '11 at 18:23
@dark_charlie: Made the answer a CW and accepted your answer. I also shorted the code a bit more. –  Kevin Brown Feb 18 '11 at 0:57
Thanks. Nice improvement! –  Karel Petranek Feb 19 '11 at 11:30

Delphi, 397 382 378 371 366 364 328 characters

Eat this Delphi!

328 var p,d:PByte;f:File;z:Word=30000;x:Int8;begin p:=AllocMem(z+z);d:=p+z;Assign(F,ParamStr(1));Reset(F,1);BlockRead(F,p^,z);repeat z:=1;x:=p^;case x-43of 1:Read(PChar(d)^);3:Write(Char(d^));0,2:d^:=d^+44-x;17,19:d:=d+x-61;48,50:if(d^=0)=(x=91)then repeat p:=p+92-x;z:=z+Ord(p^=x)-Ord(p^=x xor 6);until z=0;end;Inc(p)until x=0;end.

Here the same code, indented and commented :

  // Allocate 30000 bytes for the program and the same amount for the data :
  // Read the file (which path must be specified on the command line) :
  // Handle all input, terminating at #0 (better than the spec requires) :
    // Prevent a begin+end block by preparing beforehand (values are only usable in '[' and ']' cases) :
    z:=1;                       // Start stack at 1
    x:=p^;                      // Starting at '[' or ']'
    // Choose a handler for this token (the offset saves 1 character in later use) :
    case x-43of
      1:Read(PChar(d)^);        // ','     : Read 1 character from input into data-pointer
      3:Write(Char(d^));        // '.'     : Write 1 character from data-pointer to output
      0,2:d^:=d^+44-x;          // '+','-' : Increase or decrease data
      17,19:d:=d+x-61;          // '<','>' : Increase or decrease data pointer
      48,50:                    // '[',']' : Start or end program block, the most complex part :
        if(d^=0)=(x=91)then     // When (data = 0 and forward), or when (data <> 0 and backward)
        repeat                  //
          p:=p+92-x;            // Step program 1 byte back or forward
          z:=z+Ord(p^=x)        // Increase stack counter when at another bracket
              -Ord(p^=x xor 6); // Decrease stack counter when at the mirror char
        until z=0;              // Stop when stack reaches 0
  until x=0;

This one took me a few hours, as it's not the kind of code I normally write, but enjoy!

Note : The prime test works, but doesn't stop at 100, because it reads #13 (CR) before #10 (LF)... do other submissions suffer this problem too when running on CRLF OSes?

share|improve this answer
Wow! I never would have expected to trump C in terseness with Delphi! Not until you apply my ideas to C I guess ;-) –  PatrickvL Mar 12 '11 at 16:30

Windows PowerShell, 204

';46='write-host -n([char]$c[$i])
';91='for(;$c[$i]){';93='}'}[[int[]][char[]]"$(gc $args)"]|iex

Fairly straightforward conversion of the instructions and then Invoke-Expression.


  • 2011-02-13 22:24 (220) First attempt.
  • 2011-02-13 22:25 (218) 3e4 is shorter than 30000.
  • 2011-02-13 22:28 (216) Unnecessary line breaks. Matching on integers instead of characters is shorter.
  • 2011-02-13 22:34 (207) Used indexes into a hash table instead of the switch.
  • 2011-02-13 22:40 (205) Better cast to string removes two parentheses.
  • 2011-02-13 22:42 (204) No need for a space after the argument to Write-Host.
share|improve this answer

F#: 489 chars

The following program doesn't jump at '[' / ']' instructions, but scans the source code for the next matching token. This of course makes it kind of slow, but it can still find the primes under 100. F# integer types don't overflow but wrap.

Here's the short version:

let M a=
 let A,B,i,p,w=Array.create 30000 0uy,[|yield!System.IO.File.ReadAllText a.[0]|],ref 0,ref 0,char>>printf"%c"
 let rec g n c f a b=if c then f i;if B.[!i]=a then g(n+1)c f a b elif B.[!i]=b then(if n>0 then g(n-1)c f a b)else g n c f a b
 while !i<B.Length do(let x=A.[!p]in match B.[!i]with|'>'->incr p|'<'->decr p|'+'->A.[!p]<-x+1uy|'-'->A.[!p]<-x-1uy|'.'->w x|','->A.[!p]<-byte<|stdin.Read()|'['->g 0(x=0uy)incr '['']'|']'->g 0(x>0uy)decr ']''['|_->());incr i

A nasty gotcha was that the primes.bf program chokes on windows newlines. In order to run it I had to save the input number to a UNIX formatted text document and feed it to the program with a pipe:

interpret.exe prime.bf < number.txt

Edit: entering Alt+010 followed by Enter also works in Windows cmd.exe

Here's the longer version:

let Main args =
    let memory = Array.create 30000 0uy
    let source = [| yield! System.IO.File.ReadAllText args.[0] |]
    let memoryPointer = ref 0
    let sourcePointer = ref 0
    let outputByte b = printf "%c" (char b)
    let rec scan numBraces mustScan adjustFunc pushToken popToken =
        if mustScan then
            adjustFunc sourcePointer
            if source.[!sourcePointer] = pushToken then
                scan (numBraces + 1) mustScan adjustFunc pushToken popToken
            elif source.[!sourcePointer] = popToken then
                if numBraces > 0 then scan (numBraces - 1) mustScan adjustFunc pushToken popToken
                scan numBraces mustScan adjustFunc pushToken popToken 

    while !sourcePointer < source.Length do
        let currentValue = memory.[!memoryPointer]
        match source.[!sourcePointer] with
            | '>' -> incr memoryPointer
            | '<' -> decr memoryPointer
            | '+' -> memory.[!memoryPointer] <- currentValue + 1uy
            | '-' -> memory.[!memoryPointer] <- currentValue - 1uy
            | '.' -> outputByte currentValue
            | ',' -> memory.[!memoryPointer] <- byte <| stdin.Read()
            | '[' -> scan 0 (currentValue = 0uy) incr '[' ']'
            | ']' -> scan 0 (currentValue > 0uy) decr ']' '['
            |  _  -> ()
        incr sourcePointer
share|improve this answer
I solved the Enter issue by not pressing it but Ctrl+J :-) –  Joey Feb 14 '11 at 8:11
Ctrl+J didn't work for me, but entering Alt+010 followed by Enter did. –  cfern Feb 14 '11 at 9:28

C, 374 368

Reads from a file. Passes PRIME.BF test.

Usage: ./a.out PRIME.BF

#include <stdio.h>
main(int c,char**v){int m[30000],s[99],p=0,i=0,n=0;char l[9999],d;FILE*f=fopen(v[1],"r");for(l[i]=0;i<9999&&l[i]!=EOF;l[i]=getc(f))i++;for(i=1;d=l[i];i++){if(!n){p+=d-62?0:1;p-=d-60?0:1;m[p]+=d-43?0:1;m[p]-=d-45?0:1;if(d==46)putchar(m[p]);if(d==44){m[p]=getchar();}if(d==93){i=s[c]-1;c--;n++;}}if(d==91){if(m[p]){c++;s[c]=i;}else{n++;}}n-=d-93?0:1;}}


#include <stdio.h>
main(int c,char**v){
    int m[3000],s[99],p=0,i=0,n=0;
    char l[9999],d;
        if(!n){ // > < + - . , ] \n [ ]
share|improve this answer
3000 vs 30000. Your buffer is too small. The program size is too small also. –  Alexandru Jan 31 '11 at 12:54
I made a typo, fixed. What do you mean by program size? If you mean max file size, you didn't specify a minimum it should handle. –  jtjacques Jan 31 '11 at 15:27

C, 333 characters

This is my first BF interpreter and the first golf I actually had to debug.

This runs the prime number generator on Mac OS X/GCC, but an additional #include<string.h> may be necessary at a cost of 19 more characters if the implicit definition of strchr doesn't happen to work on another platform. Also, it assumes O_RDONLY == 0. Aside from that, leaving int out of the declaration of M saves 3 characters but that doesn't seem to be C99 compliant. Same with the third * in b().

This depends on the particulars of ASCII encoding. The Brainfuck operators are all complementary pairs separated by a distance of 2 in the ASCII code space. Each function in this program implements a pair of operators.

char C[30000],*c=C,o,P[9000],*p=P,*S[9999],**s=S,*O="=,-\\",*t;
b(){if(o>0)*c?p=*s:*--s;else if(*c)*++s=p;else while(*p++!=93)*p==91&&b();}
main(int N,char**V){
share|improve this answer
I think you can shrink it more by using the 'e' notation for all the big numbers. –  luser droog Aug 16 '11 at 4:34
@luser: I was initially surprised too, but the language and compiler won't allow that. I did manage to shrink another 4 chars with tweaks, and using a #define instead of the function table would also probably be terser. I just like the number 333 and the table :v) . –  Potatoswatter Aug 16 '11 at 5:56
Oh, right. I really should've known that. E-notation is in the production for a floating-point constant, whereas a declaration requires an integer. BTW, this may be cheating, but check out nieko.net/projects/brainfuck for Urban Müller's version. The biggest gain appears to be heavy use of ||. –  luser droog Aug 16 '11 at 6:10

C, 267

#define J break;case
char*p,a[40000],*q=a;w(n){for(;*q-93;q++){if(n)switch(*q){J'>':++p;J'<':--p;J'+':++*p;J'-':--*p;J'.':putchar(*p);J',':*p=getchar();}if(*q==91){char*r=*p&&n?q-1:0;q++;w(r);q=r?r:q;}}}main(int n,char**v){p=a+read(open(v[1],0),a,9999);*p++=93;w(1);}

Run as ./a.out primes.bf

Ungolfed Version:

#define J break;case

char*p,a[40000],*q=a; // packed so program immediately followed by data

    for(;*q-93;q++){ // until ']'
        if(n)switch(*q){ // n = flagged whether loop evaluate or skip(0)
        if(*q==91){char*r=*p&&n?q-1:0;q++;w(r);q=r?r:q;} // recurse on '[', record loop start

main(int n,char**v){
    *p++=93; // mark EOF with extra ']' and set data pointer to next
    w(1); // begin as a loop evaluate
share|improve this answer

PHP - 208 characters

<?$a=array_fill(0,3e4,$b=0);$A='$a[$b]';$c=explode('|',"|while($A){|}|echo chr($A);|$A=ord(fgetc(STDIN));|++$A;|--$A;".'|++$b;|--$b;');eval(preg_replace('~.~e','$c[strpos(" [].,+-><","\0")]',`cat $argv[1]`));

Tested with PRIME.BF

php ./bf.php PRIME.BF
Primes up to: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 
share|improve this answer

golfscript, partial solution only, 150 chars

:i;[0]30000*[]0 "#{File.open('f').read}"{{\(@=\''if}+['>+\\(@\\' '<@+\\)' '+1+256%' '-1- 256%' ".[0$]''+print " ',;i(\:i;' '[{.}{' ']}while']\%}%~;;;;

i am greatly indebted to the pattern of generating your own source and then eating it, as others have already posted.


  • only parses brainfuck code from the file 'f'.
  • all input you want to read with ',' must be piped in at the beginning.
  • runs hello world, yet dies somewhere during prime.bf. i'm not sure why. i did read somewhere that golfscript is broken for nested while loops, so that might be it.
  • stores a char=>string map in a way that is entertainingly horrible, at least to me.

I've tried loading arbitrary files with constructions like "#{File.open(" "some_file.bf" ").read}" + + but Ruby seems to helpfully escape the "#" for me so i dont accidentally load the file im trying to load. On the other hand, embedding "#{getc}" works okay for reading from stdin, but there's still the restriction that input is non-interactive - only stuff piped in at the start is read. Anyone know a way around one or more of these input issues?

share|improve this answer
The way round the first problem is to build a string consisting of a string literal and then ~ it. See my blog post on using this for debugging. –  Peter Taylor Sep 10 '12 at 12:34

OCaml(lex), 497 chars

OCamllex is part of the standard distribution of OCaml.

{let a=Array.create 30000 0
let(%)f g h=f(g h)
let s v i=a.(i)<-v;i
let o d i=s(a.(i)+d)i
let p i=print_char(Char.chr a.(i));flush stdout;i
let r i=s(Char.code(input_char stdin))i
let rec w g i=if 0=a.(i)then i else w g(g i)
let n x=x}
rule t f=parse
|'+'{t((o 1)%f)lexbuf}
|'['{t((w(t n lexbuf))%f)lexbuf}
|_{t f lexbuf}
{let _=t n(Lexing.from_channel(open_in Sys.argv.(1)))0}

Save as b.mll and run with

ocamllex b.mll && ocaml b.ml prime.bf

I don't like parsing by hand, so I used the provided lexer generator. From the tokens read, we compose a function for the whole brainf*ck program.

share|improve this answer

I created a C program which can be found here.

main(int a,char*s[]){int b[atoi(s[2])],*z=b,p;char*c=s[1],v,w;while(p=1,
v<w?c++:c--,p+=*c==v?1:*c==w?-1:0;}c++;}}//gcc -D"q(a,b)"="*c-a||(b);"

290 characters, has to be compiled via gcc -D"q(a,b)"="*c-a||(b);" -o pmmbf pmmbf.c and can be called as follows: pmmbf ",[.-]" 30000 whereby the first argument (quoted) contains the bf-program to run, the second determines how large the tape should be.

share|improve this answer
I think that you need to add 23 characters to your count for the -D"q(a,b)"="*c-a||(b);" option, since that seems (to my limited understanding, at least) to be helping you shrink your code. –  Gareth Aug 5 '11 at 9:23
The option is included in the posted text. The reason for it is to avoid the lengthy word define and newline, but I don't think that's really kosher. Anyway with the quotes, comment, and gcc -D I don't see the advantage at all. –  Potatoswatter Aug 6 '11 at 3:30

Lua, 285

loadstring("m,p={0},1 "..io.open(arg[1]):read"*a":gsub("[^.,<>[%]+-]",""):gsub(".",{["."]="io.write(string.char(@)) ",[","]="@=io.read(1):byte() ",["<"]="p=p-1 ",[">"]="p=p+1 @=@or 0 ",["["]="while @~=0 do ",["]"]="end ",["+"]="@=(@+1)%256 ",["-"]="@=(@-1)%256 "}):gsub("@","m[p]"))()

Somewhat readable version:

loadstring( --execute
    "m,p={0},1 ".. --initialize memory and pointer
    io.open(arg[1]) --open file
        :read"*a" --read all
            :gsub("[^.,<>[%]+-]","") --strip non-brainfuck
                :gsub(".", --for each character left
                    {["."]="io.write(string.char(@)) ", -- '@' is shortcut for 'm[p]', see below
                    [","]="@=io.read(1):byte() ",
                    ["<"]="p=p-1 ",
                    [">"]="p=p+1 @=@or 0 ", --if a before unexplored memory cell, set to 0
                    ["["]="while @~=0 do ",
                    ["]"]="end ",
                    ["+"]="@=(@+1)%256 ", --i like it overflowing
                    ["-"]="@=(@-1)%256 "
                    :gsub("@","m[p]") --replace the '@' shortcut
    ) --loadstring returns a function
() --call it

Works perfectly

Lua, 478, w/o loadstring

local m,p,i,r,c={0},1,1,{},io.open(arg[1]):read"*a"while i<=#c do(({[43]=function()m[p]=(m[p]+1)%256 end,[45]=function()m[p]=(m[p]-1)%256 end,[62]=function()p=p+1 m[p]=m[p]or 0 end,[60]=function()p=p-1 end,[46]=function()io.write(string.char(m[p]))end,[44]=function()m[p]=io.read(1):byte()end,[91]=function()if m[p]==0 then i=select(2,c:find("%b[]",i))else r[#r+1]=i end end,[93]=function()if m[p]==0 then r[#r]=nil else i=r[#r] end end})[c:byte(i)]or function()end)()i=i+1 end

Readable version:

local m,   p, i, r,  c= --memory, pointer, brackets stack, code
      {0}, 1, 1, {}, io.open(arg[1]) --open file
              :read"*a" --read it
while i<=#c do --while there's code
                [43]=function() -- +
                [45]=function() -- -
                [62]=function() -- >
                    p=p+1 m[p]=m[p]or 0 --if new memory cell, set it to 0
                [60]=function() -- <
                [46]=function() -- .
                [44]=function() -- ,
                [91]=function() -- [
                    if m[p]==0 then
                        i=select(2,c:find("%b[]",i)) --find matching ]
                        r[#r+1]=i --push position to the stack
                [93]=function() -- ]
                    if m[p]==0 then
                        r[#r]=nil --pop from stack
                        i=r[#r] --go to position on the top of stack
        )[c:byte(i)] --transform character into code
        or function()end --do nothing on non-brainfuck
    )() --run the resulting function
    i=i+1 --go to the next opcode
share|improve this answer

Lua (to long)

I made some Lua implementation, but I can't get the bracket stuff right. Here it is anyway:

-- >    increment the data pointer (to point to the next cell to the right).
-- <    decrement the data pointer (to point to the next cell to the left).
-- +    increment (increase by one) the byte at the data pointer.
-- -    decrement (decrease by one) the byte at the data pointer.
-- .    output a character, the ASCII value of which being the byte at the data pointer.
-- ,    accept one byte of input, storing its value in the byte at the data pointer.
-- [    if the byte at the data pointer is zero, then instead of moving the instruction pointer forward to the next command, jump it forward to the
--      command after the matching ] command*.
-- ]    if the byte at the data pointer is nonzero, then instead of moving the instruction pointer forward to the next command, jump it back to the
--      command after the matching [ command*.
s=setmetatable({0},{__index=function() return 0 end})

i=1 -- index array
j=1 -- index input
fh=arg[1] and io.open(arg[1]) or io.stdin
for k=1,#I do io.write(k%5==1 and"+"or"-") end
for k=1,math.ceil(#I/5) do local n=5*(k-1)+1 local s=(" "):rep(4-math.floor(math.log10(n))) io.write(n,s) end
"i=i+1 ",   -- array index ++
"i=i-1 ",   -- array index --
"s[i]=(s[i]+1)%256 ",   -- byte + 1
"s[i]=(s[i]-1)%256 ",   -- byte - 1
"io.write(string.char(s[i])) ", -- put byte
"local c=io.read(1):byte()s[i]=c==10 and s[i] or c",        -- read byte "Newline required!"
[=[if s[i]==0 then
        if dbg then print(j,"Forward!",o,b) end
        o= b=='['and o+1 or b==']' and o-1 or o;
    until b==']' and o == 0
]=],    -- jump to matching ]
if s[i]~=0 then
        if dbg then print(j,"Backwards",o,b) end
        o= b=='['and o-1 or b==']' and o+1 or o;
    until b=='[' and o == 0
]=],    -- jump to matching ]
for k,v in ipairs(f) do f[t:sub(k,k)],e=l(v) if e then error(e)end end
function run()
while j<=#I do
res,err = pcall(run)
if not res then
    print('Dumping state')
    for k,v in pairs(s) do print("",k,v) end
if debug then
    for k,v in pairs(s) do print(k,v) end

It doesn't pass the prime test, but acts nicely with Hello World and all echo and reverse examples I tried. So if anyone sees the bug, feel free to catch it.

share|improve this answer

From sepp2k solution - 148

eval"a=[i=0]*3e4;"+$<.bytes.map{|b|{?.,"putc a[i]",?,,"a[i]=getc",?[,"while a[i]>0",?],"end",?<,"i-=1",?>,"i+=1",?+,"a[i]+=1",?-,"a[i]-=1"}[b]}*";"

eval"a=[i=0]*3e4;"+$<.bytes.map{ can be replaced with a=[i=0]*3e4;eval$<.bytes.map{ -3 bytes

*";" => *$/ -1 bytes

"while a[i]>0" and"end" => "(" and ")while(a[i]>0)" -1 bytes

And we get 143 (5 bytes less)

a=[i=0]*3e4;eval$<.bytes.map{|b|{?.,"putc a[i]",?,,"a[i]=getc",?[,"(",?],")while a[i]>0",?<,"i-=1",?>,"i+=1",?+,"a[i]+=1",?-,"a[i]-=1"}[b]}*$/

And what if there aren't any comments in input (only +-<>[],.) http://codepad.org/EihHsoJO

we can write like this:

a=[i=0]*3e4;eval$<.bytes.map{|b|%w{putc(a[i]) a[i]=getc ( )while(a[i]>0) i-=1 i+=1 a[i]+=1 a[i]-=1}[".,[]<>+-\n".index b]}*$/

And this is 126 bytes, if there wouldn't be "\n" at the end, we can skip it in this part ".,[]<>+-\n" => ".,[]<>+-" saving 2 bytes

And this can be shorten to:

a=[i=0]*3e4;eval$<.bytes.map{|b|%w{i-=1 ( i+=1 )while(0<a[i]) a[i]+=1 a[i]=getc a[i]-=1 putc(a[i])}[b%30%9]}*$/

which is 112 bytes

where b%30%9 is a mapping from ascii code to array index

How to find this formula?

Very easy:

(1..99).each do |i|
    (1..99).each do |j|
        r = c.each_byte.map {|a| a%i%j}.select {|x| x < c.size}.uniq
        puts "#{r} #{i} #{j} " if r.size==c.size

[0, 1, 2, 3, 4, 5, 6, 7] 30 9  
[4, 5, 6, 7, 0, 1, 2, 3] 43 13  
[4, 3, 6, 5, 7, 0, 1, 2] 44 12  
[0, 7, 2, 1, 3, 4, 5, 6] 52 8  
[0, 7, 2, 1, 3, 4, 5, 6] 60 8

So if only we can assume, that there would be only <>+-[],. whe can shorten the solution to 112 bytes

share|improve this answer


C++11, 355, reads from file:

char b[30000],g[9999],*f=g,*p=b,n[]="+-,.><[]",j;




C++11, 391, to see running: http://ideone.com/yZHVv

main(int c,char **a) {
  char b[30000],g[9999],*f=g,*r=f,*p=b;
  while (c=*(f++))if(m[c]&&(r||c==']'))m[c]();
share|improve this answer

C# (2861 char, ~84 lines)

This is not the prettiest solution to the problem, and probably not all that 'Golf-ish', since I wasn't as concerned with length as I probably should have been. (I didn't remove the comments or extra white space.) I just wanted to try something in a new language, to see if I could. If I did it again, I'd drop the use of the stack for returning from ']' and just look back. Run without command line arguments it runs the hello world program given in the problem description. It accepts one command line argument, the filename of the program to run.

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
    class Program
        static void Main(string[] args)
            String ProgSource;
            if (args.Length > 0)
                ProgSource = System.IO.File.ReadAllText(args[0]);
            else //hello world
                ProgSource = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.";

            Stack<int> stack = new Stack<int>();
            char[] bfProg = ProgSource.ToCharArray();
            char[] mem = new char[30000];
            int ptr = 0;

            for (int ip = 0; ip<bfProg.Length; ip++){
                switch (bfProg[ip])
                    case ('>'): ptr++;  break;
                    case ('<'): ptr--;  break;
                    case ('+'): mem[ptr]++; break;
                    case ('-'): mem[ptr]--; break;
                    case ('.'): Console.Write(mem[ptr]); break;
                    case (','): 
                        char key = Console.ReadKey(false).KeyChar;
                        if (key == '\r')
                            key = (char)10;
                        mem[ptr] = key;
                    case ('['):
                        if (mem[ptr] == 0)
                            int openBraces = 1;
                            //find the closing brace for this expression
                            for (int x = 1; x < (bfProg.Length - ip); x++)
                                if (bfProg[ip + x] == ']') openBraces--;
                                if (bfProg[ip + x] == '[') openBraces++;
                                if (openBraces == 0)
                                    if (stack.Peek() == ip) stack.Pop();
                                    ip += x;
                    case (']'):
                        if (mem[ptr] == 0)
                            ip = stack.Peek();

            Console.WriteLine("\n\n\nExecution Completed Sucessfully. Press any key to continue...");



Edit: Removed unused references.

share|improve this answer

C: 317 characters (reads from a file)

#include <stdio.h>
char t[30000],*p=t,b[30000],c;void r(char*a){while((c=*a++)&&c-93){p+=c==62;p-=c==60;*p+=c==43;*p-=c==45;c^46||putchar(*p);c^44||(*p=getchar());if(c==91){while(*p)r(a);c=1;while(c+=(*a==91)-(*a++==93));}}}int main(int n,char**a){FILE*f;f=fopen(a[1],"r");fread(b,1,30000,f);fclose(f);r(b);return 0;}

This is my brainfuck interpreter that I wrote for a couple of months ago, it's quite a bit longer than it needs to be, but that is because I didn't focus on size when I wrote it, I focused on readability (just the fact that it compiles without error and even includes a library suggest that it is heavily shrinkable).

And expanded:

#include <stdio.h>
char t[30000],*p=t,b[30000],c;
void r(char*a){
int main(int n,char**a){
    return 0;

I might return with an actually golfed version.

share|improve this answer

Racket (20)

#lang planet dyoo/bf

This is pretty much cheating. Also, you would need to supply the Brainfuck code in the program's source itself.

share|improve this answer

JavaScript - Partial Solution (241 235)

Does not read from file - does not manage PRIMES.BF, but works for Hello World!

// not included in 235 count, the hello world code from wikipedia
var p="++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.",

// partial solution - dies on primes
eval(p.replace(/[^\][.,+><-]/g,'').replace(/(.)/g,function(e){return "0while(a[b]){0}0console.log(String.fromCharCode(a[b]))0a[b]=prompt()0++a[b]0--a[b]0++b0--b".split(0)[" [].,+-><".search(new RegExp("\\"+e))]+";"}))

Just copy and paste it into javascript console to see it in action. Works in node.js, or broswer.

I was hoping to get PRIMES.BF to work in node.js, but not been able to emulate STDIN in a synchronous way yet.

With comments

// should read from file - easy with node.js
// this is the `Hello World! ` program from wikipedia
var p="++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.",

// declare a and b. If a needs to be longer, can use:
//     a=[];for(0;a.length<30000;a.push(0))b=0

// evaluate
  // the brainfuck code
  // replacing all the non brainfuck commands with nothing 
  // replacing all commands (captured in parenthesis) with callback
     // return swapped commands
     return "0while(a[b]){0}0console.log(String.fromCharCode(a[b]))0a[b]=prompt()0++a[b]0--a[b]0++b0--b"
     // split into array on the 0 (used as seperator - shorter than "|" when
     // called in .split(0) function)
       // matching brainfuck commands
       " [].,+-><"
       // searched with escaped, captured command
       .search(new RegExp("\\"+e))
       // add a semicolon to all statements - extra semicolons do not interfere
       // with execution of javascript
share|improve this answer


I did write this one in F# don't know what it is in chars but its ~50LoC.BrainFuck in F#

share|improve this answer
You should post the code here so we can look at it. –  syb0rg Dec 11 '13 at 3:06
@syb0rg Why not just follow the link. –  Adam Speight Dec 11 '13 at 3:08
I can now, but in the future link rot may occur. Plus, everyone else wants so see the beautiful code you programmed as soon as possible! –  syb0rg Dec 11 '13 at 3:11
Also, here you can calculate the character count. –  syb0rg Dec 11 '13 at 3:18
@syb0rg Character count is hard to determine the typically quoted count is excluding whitespace, but that wrongly includes significant whitespace (like F#). Any program written in the BF derivative language WhiteSpace would have score of 0. –  Adam Speight Dec 11 '13 at 3:29

Smalltalk, Squeak 4.x flavour 414 chars

Here is an interpreter which works exclusively with streams and block closures:

b:=[:c :i :o :n |
| v |
v := 1 to: n.
v := (v collect: [:x| | t |
    t := 0.
    Dictionary newFrom: {
        $+ -> [t:=t+1\\256].
        $- -> [t:=t-1\\256].
        $. -> [o nextPut:t].
        $, -> [t:=i next].
        $< -> [v back].
        $> -> [v next].
        $[ -> [t=0 and: [
            [c next=$[
                ifTrue: [(v peek at: $[) value].
             c peek=$]] whileFalse.
            c next]].
        $] -> [t=0 or: [c back.
            [c back=$]
                ifTrue: [(v peek at: c next) value. c back;back].
             c peek=$[] whileFalse.
            c next]].
        }]) readStream.
[c atEnd] whileFalse: [(v peek at: c next ifAbsent: [[]]) value]]
  • c is a readStream on code
  • i is a readStream on input (a ByteArray)
  • o is a writeStream on output (a ByteArray)
  • v is a readStream on interpreters (an Array)
  • n is number of cells

For each cell, we create an interpreter - that is a Dictionary which associate a Block to each BF command (a Character).
Those blocks close over a value t, initialized at zero.
The jump instructions are implemented recursively.
The pointers (code and data) are hidden in streams state.

To use the interpreter, we just have to feed this block with proper streams:

c := 'http://esoteric.sange.fi/brainfuck/bf-source/prog/PRIME.BF' asUrl retrieveContents contents readStream.
i := '15\' withCRs withUnixLineEndings asByteArray readStream.
o := #[] writeStream.
n := 30000.
b valueWithArguments: {c.i.o.n}.
^'',o contents

The interpreter can be golfed to 414 chars, using as:Dictionary which is shorter and by removing overflow and underflow protections (the cell value is then unbound).

b:=[:c :i :o :n||v|v:=1to:n.v:=(v collect:[:x||t|t:=0.{$+->[t:=t+1].$-->[t:=t-1].$.->[o nextPut:t].$,->[t:=i next].$<->[v back].$>->[v next].$[->[t=0and:[[c next=$[ifTrue:[(v peek at:$[)value].c peek=$]]whileFalse.c next]].$]->[t=0or:[c back.[c back=$]ifTrue:[(v peek at:c next)value.c back;back].c peek=$[]whileFalse.c next]]}as:Dictionary])readStream.[c atEnd]whileFalse:[(v peek at:c next ifAbsent:[[]])value]].
share|improve this answer

Python 2, 223

I admit that I recycled an old program of mine (but had to change it quite a bit, because the old version didn't have input, but error checking...).

import os,sys
for c in open(sys.argv[1]).read():x="><+-.[,]".find(c);P+=" "*i+"i+=1 i-=1 a[i]+=1 a[i]-=1 os.write(1,chr(a[i])) while+a[i]: a[i]=ord(os.read(0,1)) 0".split()[x]+"\n";i+=(x>4)*(6-x)
exec P

Runs the primes calculator fine.

I see now that Alexandru has an answer that has some similarities. I'll post mny answer anyways, because I think there are some new ideas in it.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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