25
\$\begingroup\$

Now, a while ago, I said in chat:

I'm done with BF programming.

Except I guess I was lying. Here's a Brainfuck program I wrote, that prints out the multiplication tables up to 12. Fairly simple; what it does:

  1. Loops through 1-12; let's say the current value we are at is x
    • Loop 12 times, adding x each time, and prints the result
    • Resets the number

The code:

Cell 0 is space
Cell 1 is newline
Cell 2 is outer counter
Cell 3 is outer number
Cell 4 is inner counter
Cell 5 is inner number
Cell 6 is copy workspace

>++++[<+++++ +++>-]                                 set cell 0 to space
+++++ +++++                                         set cell 1 to new line

>+++++ +++++ ++                                     set counter to 12
[                                                   while counter is not 0
    >+                                              increment number
    >+++++ +++++ ++                                 set inner counter to 12
    [                                               while inner counter is not 0
        <[>>+>+<<<-]>>>[<<<+>>>-]                   increment inner number

        >++++++++++<<[->+>-[>+>>]>[+[-<+>]>+>>]
        <<<<<<]>>[-]>>>++++++++++<[->-[>+>>]>
        [+[-<+>]>+>>]<<<<<]>[-]>>[>++++++
        [-<++++++++>]<.<<+>+>[-]]<[<[->-<]++++++
        [->++++++++<]>.[-]]<<++++++[-<++++++++>]
        <.[-]<<[-<+>]                               print number gotten off SO

        <<<<<<.                                     print space
        >>>>-                                       go to inner counter
    ]                                               end inner loop
    >[-]<                                           reset number
    <<<.                                            print new line
    >-                                              go to counter
]                                                   end outer loop

Compressed:

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

Output:

1 2 3 4 5 6 7 8 9 10 11 12 
2 4 6 8 10 12 14 16 18 20 22 24 
3 6 9 12 15 18 21 24 27 30 33 36 
4 8 12 16 20 24 28 32 36 40 44 48 
5 10 15 20 25 30 35 40 45 50 55 60 
6 12 18 24 30 36 42 48 54 60 66 72 
7 14 21 28 35 42 49 56 63 70 77 84 
8 16 24 32 40 48 56 64 72 80 88 96 
9 18 27 36 45 54 63 72 81 90 99 108 
10 20 30 40 50 60 70 80 90 100 110 120 
11 22 33 44 55 66 77 88 99 110 121 132 
12 24 36 48 60 72 84 96 108 120 132 144 

Some notes:

  • The multiplication table is missing formatting. I realise that, and will add it some time later, if I can figure out how to compare two values.
  • I realise it doesn't work for multiplication tables of 16 or higher, due to BF cell sizes being only 8 bits, or up to 255. The value 16 * 16 would result in 256, setting the value of the cell to be 0. Is this unavoidable? Or is there a trick to it?

Concerns:

  1. Does it make sense? (Considering it's Brainfuck, it shouldn't make sense...)
  2. Do my "comments" make sense?
  3. Are there redundant commands that I can remove/reduce?
\$\endgroup\$
  • 13
    \$\begingroup\$ "Does it make sense?" "Brainfuck" pick one \$\endgroup\$ – Dan Pantry Nov 29 '15 at 0:18
  • 4
    \$\begingroup\$ It probably makes no sense outside mind training. Bending your mind a little bit is usually useful, as it brings it where you're not used to go. \$\endgroup\$ – gazzz0x2z Dec 4 '15 at 7:48
  • 3
    \$\begingroup\$ Upvoted because the idea of your willpower cracking in the face of a BF addiction makes me happy. <3 \$\endgroup\$ – Jonah Dec 13 '15 at 5:24
9
+50
\$\begingroup\$

The multiplication table is missing formatting. I realise that, and will add it some time later, if I can figure out how to compare two values.

Comparing two values isn't that complicated, once you know how to do it. It is however extremely inefficient if you do it over and over again. Your best bet would be to hook into the printing of the number and print spaces if there are no hundreds or tens.

I managed to do a little proof-of-concept for this, which I am sure can be optimized further. The idea is the following:

  • Before the loop that prints the number of 100's, set a temporary flag on another cell
  • If the loop is entered, reset the temporary flag at the end
  • Outside the loop, go to temporary flag and if it is set, print a space. Clear the flag and go back to the cell.

The unformatted and unoptimized version of this enhanced "print the number" code is as follows:

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

>>>+<<<[

    [x>++++++[-<++++++++>]<.<<+>+>[-]]

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

<

>>>+<<<[
    [y<[->-<]++++++[->++++++++<]>.[-]]
>>>-<<<]>>>[++++++++++ ++++++++++ ++++++++++ + . [-]]<<<


<<++++++[-<++++++++>]
        <.[-]<<[-<+>]                               print number gotten off SO

I have marked the loop where the 100's are printed with x and the loop for the 10's with y, to make it easier for you to see the changes I did.

I realise it doesn't work for multiplication tables of 16 or higher, due to BF cell sizes being only 8 bits, or up to 255. The value 16 * 16 would result in 256, setting the value of the cell to be 0. Is this unavoidable? Or is there a trick to it?

There are some different possible solutions to this:

I am unfortunately only experienced with using a Brainfuck interpreter that supports higher values. I don't know at all how the Bit-width conversions work, or how you are gonna do the number printing then.

Does it make sense? (Considering it's Brainfuck, it shouldn't make sense...)

Do my "comments" make sense?

Surprisingly much sense, yes. For a Brainfuck developer your code is quite easy to follow and your comments are helpful.

Are there redundant commands that I can remove/reduce?

There are two places in your code where I am, without doing over-analysis, able to find optimization possibilities: How you structure your memory, and how you print the numbers.

When structuring the memory, think about which places you need to go, and in which order. Currently you have positioned the space (value 32) at index 0 on the tape, and yet it is one of the most accessed values. Positioning that closer to the "inner number", will allow you to go to it more easily.

The printing of the number is a common algorithm found at Stack Overflow, which is fine. But I have realized that it is a bit inefficient for printing multiple numbers, as it goes from value 0 to value 48 (ASCII value for '0') multiple times, and resets to 0 every time. It would be better to initialize a '0' into a cell and re-use that cell multiple times, without resetting it.

|improve this answer|||||
\$\endgroup\$
1
\$\begingroup\$

1) It makes sense. You made yourself a challenge and mastered it

2) The comments make sense, too. They are made for you but i can easily understand them, too

3) There are a few things you can optimize. When initializing your tape, you can multiply several values at once, so instead of this:

>++++[<+++++ +++>-] set cell 0 to space
+++++ +++++         set cell 1 to new line
>+++++ +++++ ++     set counter to 12

you can do that:

+++++ +++++[->+++>+>+<<<][set values to 0, 30, 10, 10]
>++>>++                   set values to 0 32 10 12

It's not a problem to have a leading 0 on your tape. Then you can rearrange your variables to make the copy instruction and the jump to the space character shorter.

You can use a shorter number printing function that's available on esolangs.org.

This is what I made of your code. There's not much change, but it shrinked from 310 to 233 bytes.

Tape: [0] [lf] [outCount] [" "] [inCount] [outNr] [inNr] [temp] [0] [printNr]
       0   10   12         32

+++++ +++++ [->+>+>+++<<<]                          set first cells to 0 10 10 30
>>++>++                                             set first cells to 0 10 12 32
<[                                                  while counter is not 0
    >>>+                                            increment number
    <+++++ +++++ ++                                 set inner counter to 12
    [                                               while inner counter is not 0
        >[>+>+<<-]>>[<<+>>-]                        increment inner number

        <[->+>>+<<<]>[-<+>]>                        copy inner number to print number
                                                    (must be done for new number printing routine)

        >>+[[-]<[->+<[->+<[->+<[->+<[->+<[->+<[
        ->+<[->+<[->+<[->[-]>>+>+<<<]]]]]]]]]<]
        >>[>]++++++[-<++++++++>]>>]<<<[.[-]<<<]     use number printing routine from esolangs[.]org
                                                    (exits at temp)
        <<<<.                                       print space
        >-                                          go to inner counter
    ]                                               end inner loop
    >>[-]                                           reset number
    <<<<<.                                          print new line
    >-                                              go to counter
]                                                   end outer loop
|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ I've made another little change so that the table will be formatted with leading "0"s. \$\endgroup\$ – Dorian Jul 4 '18 at 9:03
  • \$\begingroup\$ I've made another little change so that the table will be formatted with leading "0"s. The number printing routine uses three cells for each digit. It divides the number by ten, leaves the remainder one cell to the right and the result of the division three cells to the right of the current cell, then adds 48 to the remainder, so it is printable and then does the same with the result of the division until the result is 0. \$\endgroup\$ – Dorian Jul 4 '18 at 9:10
  • \$\begingroup\$ I changed it in a way that it continues until the result is -1. This will never happen by itself, so i marked the third number with -1 and the printing routine will print three digit numbers with leading zeroes. ` >> >>> >>> >>>- set flag for aborting number print <<< <<< <<< return to start of number printing routine +[[-]<[->+<[->+<[->+<[->+<[->+<[->+<[- >+<[->+<[->+<[->[-]>>+>+<<<]]]]]]]]]<]> >[>]++++++[-<++++++++>]>>+]<<<[.[-]<<<] use number printing routine from esolangs[.]org` \$\endgroup\$ – Dorian Jul 4 '18 at 9:11
-1
\$\begingroup\$

I think I came up with a solution to printing values greater than 16*16. Is it possible to print values without spaces between them? If so I'm sure there's some way to make 16*16 come out to 25 and then without a space in-between 5 (or 2 and then 56) and do that with all values greater than 255.

As for your concerns: 1) It works so it must make sense
2) I don't see anything wrong with your comments
3) I don't see anything glaringly inefficient. Isn't that sort of the point of the language? To be really minimalist and efficient.

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ I don't quite understand how exactly you're planning on doing that printing of values more than or equal to 256... I'm not even sure that you understand exactly what the problem is with it. \$\endgroup\$ – Simon Forsberg Dec 13 '15 at 9:41
  • \$\begingroup\$ The problem is that each cell can only go up to 255. So, the only way to print a number larger would be to combine two cells when printing. \$\endgroup\$ – Ulthran Dec 13 '15 at 16:48
  • \$\begingroup\$ not only when printing, also when calculating, as currently the values is stored in a single cell. So even if you could print values higher than 255 (which the current code technically can, it can support up to 999), how would you calculate and store the value in the first place exactly? That's a bigger problem than printing values without spaces between them. \$\endgroup\$ – Simon Forsberg Dec 13 '15 at 16:57
  • \$\begingroup\$ I wasn't saying I knew how to do that part of it. I was just suggesting that not having spaces would be a start. \$\endgroup\$ – Ulthran Dec 13 '15 at 20:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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