flaw600 - 5 months ago 11

Brainfuck Question

So I'm trying to get the cells to hold such that the first cell holds null (0), the second holds 9*4, the second, 9*10, the third 9*12, the 4th, 9*13, and so on until the last cell in use has 9*15. That is, the following code so far in brainf*ck:

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

Is there anyway to condense this code? That is, have the proper cells hold the numbers in question but use less characters to do it? I thought of using nested loops but I'm not exactly sure how to construct such a thing. I'm new to the language and I'm trying to test it out and I think I'm overthinking the problem. Thanks!

Answer

To use inner loops find out factors of the number you want to put in a cell.

Suppose you want to set a cell to 48

You can make the outer loop loop twice. So far so good, you use a temporary cell to hold the loop value, and increment the target cell by 24 inside so you end up with 48.

Now suppose I want to break down the body of the loop, which is currently adding 24 on every iteration. You do the same process. Find out factors of 24: for this example let's choose 6 and 4. So in the inner loop you put in a 2nd loop (which uses a 2nd temporary cell to hold the inner loop's iteration count), loop 4 times adding 6 each time. Every time this inner loop runs, the target cell ends up with 24 added to it, and the inner loop runs twice (the outer loop loops twice) so the target cell ends up with 48.

Here is the example using just 1 temporary cell

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

This uses cell 0 as the counter and sets cell 1 to 48 by adding 24 twice.

And here is the 2nd example with 3 factors: 2, 4, 6 (2*4*6==48)

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

This uses cells 0 and 1 as temporary cells, and sets the target cell (cell 2) to 48 as well. As you can see, the content of the inner loop (`++++[>++++++<-]`

) is just a normal loop like in the 1st example.

It is clearly obvious that the 2nd one is shorter, but it might run very slightly slower (not that this is a real concern... you're using BF in the first place, you're not looking for performance)

Now since you want to set multiple cells at once, it's pretty easy to apply the above to your code. You find out the factors in the same way as I described above, and put the factor that's common to all of them as the outer loop's counter, and then you construct individual inner loops for each cell inside it using their remaining factors. You could even merge some of them if any of the inner ones share factors as well.

Another trick which could shorten your code when the number isn't as cleanly divisible, is to get as close as you can to the number you want and adjust it at the end.

To use the same example I used above, If I wanted to set the cell to 49 instead of 48, I'd use the same code that sets it to 48, and then add 1 at the end (or set it to 50 and subtract 1) and the resulting code might still be shorter.