I need help understanding a brainfuck code

68 Views Asked by At
>, >, <<

convert from ascii

+++++ +++[>----- ->----- -<<-] (a)

multiply

>[>[->+>+<<]>[-<+>]<<-] (b)

separate numbers

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

[

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

 [<<<]>>>>

]

<-

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

I don't understand what this line - [>>>] does. My first guess would be that it moves 3 pointers until a pointer with a null value is reached. Except since the pointers have not even been used before, they're all 0 anyway. So the loop shouldn't even have been entered. I'd be really grateful if anyone would help me explain every part of this line:

[

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

 [<<<]>>>>

]
1

There are 1 best solutions below

0
On

There's only one pointer in brainfuck. Colloquially we say it's "at" the cell it indicates, and then it moves to another cell to indicate that one, so >>> moves the pointer three cells to the right; strictly, >>> changes the pointer's value so it indicates the cell three cells to the right of the cell it indicated before.

-[>>>] decrements the cell the pointer is at, then moves the pointer right three cells at a time until it reaches a cell holding the value 0.

The earlier parts of this program have already input two characters assumed to be 1-digit numbers, subtracted 48 from them to get the values of those digits, and multiplied them together. Just before the code you mention, the state of the memory array is 0 0 0 1 a 10 where a represents the product of the two digits, and the pointer is at the a.

So, let's say a was 3. Then it will end up doing the outer loop you asked about 3 times. The first time, it decrements a, moves pointer to the 10, decrements the 10, then because it's at a 9 (i.e. nonzero), the [>>>] moves the pointer 3 cells right, and it sets up another 10 and a 1, so the state of memory will be 0 0 0 1 a=2 9 1 0 10 with the pointer at that second 1 cell. Then the [<<<] moves the pointer 3 cells left to the first 1 cell (because the second 1 isn't 0), then another 3 cells left to the leftmost 0 cell (because the first 1 isn't zero either), then stops (because the leftmost 0 cell is a zero). Then >>>> moves the pointer back to a (now 2) and we do the whole loop again.

The next time through this loop, it will decrement a (to become 1), decrement the 9 (to become 8), then the [>>>] will move from the 8 to the 10 and then from the 10 three cells right to a 0, and set up another 10, and then scan back to the left again. Then similarly for the third iteration, and after that we end up with: 0 0 0 1 a=0 7 1 0 10 1 0 10 1 0 10 0 0 0 0 0 ...

Now, notice what happens if a was more than 9. The 10th time through, decrementing the cell to the right of a produces a 0, which means the [>>>] is skipped, which means we set that same cell to 10 again, and increment the 1 that was just left of a, producing a 2. 0 0 0 2 a 10 1 0 10 1 0 10 ...repetitions... 1 0 10 0 0 0 ... Then continue. If a was greater than 19, then when the cell right of a gets zeroed again it gets replaced by a 10 again and that 2 is incremented to become a 3.

The overall result is that after that complex loop has executed a times, we end up with:

0 0 0 x a=0 y 1 0 10 ...repetitions... 1 0 10 0 0 0 ... where x is 1 more than the tens digit of a, and y is 10 minus the ones digit of a. The whole point of this code was to break a down into its two digits. Then the last two lines of this program clean up those digits, so we end up with: 0 0 o t 0 0 1 0 10 ...repetitions...1 0 10 0 0 0 ... where o is the ones digit of a and t is the tens digit of a.

Notice that this code clutters the memory with an amount of ...1 0 10... proportional to the initial value of a.