Brainfuck Tutorial – part 2

In this tutorial I will talk more about loops and how to do basic higher level stuff in Brainfuck. If you already know BF operators, you can start from this part. Else, read the previous tutorial.

[] operators are used for creating conditional loops in BF. As long as value of current pointer is non zero (when program executes [ command), it loops between [ and ]*You obviously know this if you read previous tutorial.

So what can we do with this information? Well, pretty much everything. Here are some higher level stuff that you can do with loops.

The first and easiest one is clearing a cell. It is simply

[-]

If cell is non zero, it enters this loop and decreases it until it is zero. You might ask what is the use of this. It is usually used when implementing booleans or if conditions.

Another one is moving a cell to another.

[->+<]

Let's say our array is like this

...ab...
...^

Initially pointer points to a. With this loop it decreases a until it is zero and increases b by 1 on each iteration. So it basically moves content of a from b. (Actually if b is non zero, it is *b=*b+*a; *a=0;, in this tutorial I will assume cells are 0 unless it is specified).

And finally, copy operation

[->+>+<<]

It moves (adds) current cell to two cell on the right.

These are most basic things in brainfuck. While implementing more complex stuff, you will those a lot. For example let's draw a triangle like this.

...*
..***
.*****
*******

So in C, this is done like this.

int k = 4; //line num
int i, j;
for(i=0; i<k; i++){//for each line
   for(j=0; j<k-i-1; j++) printf(" ");
   for(j=0; j<i*2+1; j++) printf("*");
   printf("\n");
}

Implementing this directly in BF would be a lot harder, some higher level operators a lot harder to implement. I will 'simplify' it for BF.

int k = 4; //line num
int a, b, i, j;
a = k;
b = 1;
while(a--){
  i = a;
  while(i--) printf(" ");
  j = b;
  while(j--) printf("*");
  printf("\n");
  b+=2;
}

So this does the same thing but it is a lot easier for BF. Basically a holds the number of spaces while b holds the number of stars for each line. Before starting writing my program, i will first decide my structure for array.

ktabijs*n
012345678

This is my array structure that I will use in my program. First line is the name of each cell and second line is indices of each cell. I already decided which cells will hold which values. k, i, j, a, b are the values in previous C code. t is a temp cell. "s*n" are the cells that will contain ascii values for ' ' (space), '*' and '\n' (newline).

So first lets begin with building "s*n". Space is 32, '*' is 42 and '\n' is 10. I will use cell j as a temporary cell to make a loop and set these cells to correct value. Initially pointer is at cell k (0th cell).

!bf!>>>>> (move cell j)
+++++ +++++ (set j to 10)
[- (as long as j is non zero)
  > +++ (increase cell s by 3)
  > ++++ (increase cell * by 4)
  > + (increase cell n by 1)
  <<< (move back to cell j)
]

So after this code, s will be 30, * will 40 and n will be 10 (and j will be 0). But we want 32, 42 and 10 so let's increase s and * by 2

>++>++

So the cells that holds the ascii values are ready! Now let's input cell k from user. I am assuming user will enter a single digit. But it is in ascii so I have to decrease it by 48 ('0') to convert it to a real number. With the addition of previous code, now the pointer is at cell *. Move it back to cell k, input a character and decrease it by 48. While at it let

!bf!<<<<<<< (move back to cell k)
, (input a character)
> +++ +++ (set t to 6)
[ - < ---- ---- >] (decrease k by 8 for each iteration of t) (in total 48)

Now cells ks*n are ready. Now let's initialize cell a and b. a should be initially equal to k and b should be 1. In previous code we were at j.

!bf!< (move back to cell k)
[->+>+<<] (copy k to t and a)
> [-<+>] (move t back to k)
>> + set b to 1

Some of those look familiar? Basically we are creating two copies of cell k at cell t and cell a then move t back to cell k. We can't copy a cell to directly to another without clearing content of the first. We have to create 2 copies, move 1 to back.
After that it sets b to 1. So our initializing process is done. Let's look at our current structure.

!bf!k  0  k  1  0  0  32  42  10
k  t  a  b  i  j  s   *   n
0  1  2  3  4  5  6   7   8
            ^

First line holds the values, second line is the name of the cells and last line is the index of each cell. Now we can start actual programming!

First line of C code is while(a--). This is our main loop, as long as a is non zero create a loop. After beginning of each iteration it decreases a by 1 How could we achieve such a thing in Brainfuck. In our previous code, we left pointer at b. We want a loop that runs until a is non zero.

!bf!< (move back to a)
[
  - (decrease a by 1)
  {snip}
]

And that is all!. In snip part we should implement inside of the main while loop. Our first operation is printing number of spaces that is equal to a. For that we copy a to i, and print space as long as i-- is true. Pointer is at a

!bf!!nr![- <+> >>+<<] (make copies of a at t and i)
<[->+<]> (move t back to a) 
>> [->>.<<] (move to i and print spaces (cell s) until it is 0)

First we make two copies of cell a at t and i. And then move t back to a so value of a is not changed (We will need it on next iteration) after that it simply moves pointer to i, enters a loop and for each iteration it moves to cell s (contains ' ' (space)) and prints it). That is it, we already printed our spaces. Now move to the starts, it is basically same code but on different cells. (instead of a i s, it is b j *). In the last code we left pointer at cell i.

!bf!!nr!
<
[- <<+>> >>+<<] (make copies of b at t and j)
<<[->>+<<]>> (move t back to b) 
>> [->>.<<] (move to j and print stars(cell *) until it is 0)

As you can see, I just modified previous code a little. With this we printed our spaces and starts. Finally let's print a new line and end finish this line. With last code, pointer is now at cell j

!bf!!nr!>>>. (move to cell n and print it)

Finally. We printed all necessary stuff and done for this line. However before beginning to next iteration, we have to change value of a and b correctly. After each line, number of spaces is decreased by 1 (a) (which we did in the beginning) and number of stars are increased by 2. We were at cell n

!bf!<<<<< ++(move to cell b and increase it by 2)
<  (and move back to a)

That is it! We implemented {snip} part of our main loop. As you can notice, pointer is at cell a so we have to move pointer to a in the end. Let's merge all of our stuff and test it!

!bf!>>>>> (move cell j)
+++++ +++++ (set j to 10)
[- (as long as j is non zero)
  > +++ (increase cell s by 3)
  > ++++ (increase cell * by 4)
  > + (increase cell n by 1)
  <<< (move back to cell j)
]
>++>++ (set s to 32 and * to 42)

<<<<<<< (move back to cell k)
, (input a character)
> +++ +++ (set t to 6)
[ - < ---- ---- >] (decrease k by 8 for each iteration of t) (in total 48)

< (move back to cell k)
[->+>+<<] (copy k to t and a)
> [-<+>] (move t back to k)
>> + set b to 1

(while(a minus minus){)
< (move back to a)
[
  - (decrease a by 1)

  (i=a; while(i minus minus) printf(" ");
  [- <+> >>+<<] (make copies of a at t and i)
  <[->+<]> (move t back to a) 
  >> [->>.<<] (move to i and print spaces (cell s) until it is 0)

  (j=b; while(j minus minus) printf("*");
  <
  [- <<+>> >>+<<] (make copies of b at t and j)
  <<[->>+<<]>> (move t back to b) 
  >> [->>.<<] (move to j and print stars(cell *) until it is 0)

  (printf("\");)
  >>>. (move to cell n and print it)

  (b = b plus 2)
  <<<<< ++(move to cell b and increase it by 2)

  <  (and move back to a)
] (} end of while(a minus minus)

And let's remove all comments from code abd format it a little(Enter input 'a' for more fun!)

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

(I added extra >> there to make it triangle)

And we build our first complex program, yay! Before finishing my post, I want to emphasize a couple of things.

  • Before starting coding, first you should build your structure on your mind (and write it in a paper/text editor). Which cells will be used for what, name each cell etc... You should decide it at the beginning. The structure I used is not the best, I could make a more compact one and it would reduce the code size a lot.
  • Try to split your program into smaller parts. For example in this program, first part creates ascii values for printed parts, second part inputs k and initialized a and and final parts prints stuff. If you separate them like this, you can test them separately and it will be much easier to write. Use a debugger if necessary, that shows your the content of each cell and see if you are doing correctly. This one is quite good and very fast
  • Always know where your pointer is. While coding, I usually put comments that shows where am I now. For example
    !bf!!nr!
      [- <+> >>+<<]a (make copies of a at t and i)
      <t[->+<]>a (move t back to a) 
      >> i[->>.<<] (move to i and print spaces (cell s) until it is 0)
      <b
    

    I don't write comments between () they are way too unnecessary. Only occasional comments like a, b, i, t in this example that shows where is the cursor at that point of comment. I also copy paste my array structure a lot to move my pointer correctly. After a while, basic algorithms will be easy for you (like copying, moving stuff etc) as long as you know where you are.

  • With more practice, you will be able to think how to write higher level stuff in BF. You will be able to make a general algorithm in your mind and after that it is just patience.
  • Well that is all for now. This was a fairly complex program (CS 101 stuff), I hope that I explained it well. I am planning on more tutorial with more complex examples).

    Loading Facebook Comments ...

    Leave a Reply

    Your email address will not be published. Required fields are marked *