AnswerBun.com

BF welcomes Fibonnaci

Code Review Asked by Simon Forsberg on January 2, 2022

Slightly inspired by a previous question/april fools joke I decided to take on Fibonnaci sequence in the lovely language Brainfuck.

In order to do this I have also worked on Brainduck, which is a Brainfuck tool/analyzer/IDE. In Brainduck I added the functionality to run Groovy code if the line begins with $.
I wanted this to serve as both a way to make assertions while running the code, to make developing BF programs easier, and to serve as documentation. This question is not primarily about Brainduck though, but about the Brainfuck code I wrote using Brainduck.

A slight summary of the $ stuff I am using:

  • wrapValue, wrapMemory, minValue, maxValue: Sets some settings in Brainduck and also serves as documentation for what the code is compatible with.
  • name: Gives the current memory cell a name which gets displayed in Brainduck
  • assert hasName: Asserts that the current memory cell has the given name. If it doesn’t, Brainduck stops execution of the code.

Primary concerns:

  • Is this readable and understandable? (Yeah yeah, I know it’s BF we’re talking about, but somewhat readable code have been written in BF before)
  • Does my use of the $-lines makes sense? Does it help to understand the code?
  • Can it be even more optimized somehow?

How the code works:

Setup the tape to contain 255 10 0 0 0 1 0 0 0 0 1 0 0 0 49 and print 0 and 1 (the first two Fibonnaci numbers).

  • 255 is for the countdown, how many numbers to print. (Could easily be extended to print more numbers, using something similar to what I wrote in an old answer, such as using 128+128, which could also be 128*128).
  • 10 is, as we all know, the linefeed character.
  • Three zeros for some empty space.
  • A series of digits, first we initialize one digit to contain a 1. Each digit section contains:
    • 0 or 1 to indicate if the digit is being used (The longer the code runs, the more digits will be used)
    • A B and C fields, two of each (explained below) and an overflow field between B and C. Two temp fields and the digit as the ASCII value (48 to 57).

Start looping. For each enabled digit do the following:

  • Initialize 10 at the ’10 minus C’ field
  • Clear B and move A to A2 and B
  • Set A = C
  • Set C = A + B and while doing so check for overflow. If overflow occurs (10 minus C equals zero) then mark the overflow field with 1 and reset the digit to 0 (to simulate “10”)
  • After the addition, check if the overflow field is set. If it is, add 1 to the next digit and activate the next digit if it wasn’t already activated.
  • Move back the A’s B’s and C’s

After all digits has been processed, print them in the order they should appear (higher valued digits are put later in the tape, so loop the tape backwards and print the digits).

Code:

$ wrapValue CRASH
$ wrapMemory CRASH
$ minValue 0
$ maxValue 255

$ name 'countdown'
>
 +++++ +++++ 100
 +++++ +++++ 200
 +++++ 250
 [- < +++++ +++++ >] <
 +++++ 255
> +++++ +++++ Line break
$ name 'lineBreak'

Write out the first ones
>+++++ +++++ +++++ +++++ +++++ +++++ +++++ +++++ +++++ +++.<.>+.<.>[-]
$ name 'zero'

>
>
>+
$ name 'digitStart'
Digit 1 Value A
> >
Digit 1 Value B
> >
Digit 1 Value C
>+
>
>
>
>+++++ +++++ +++++ +++++ +++++ +++++ +++++ +++++ +++++ ++++
$ name 'digit'
<<<<<
<<<<< <<<<

Memory
Countdown or loop condition
New line
Two empty cells

Series of DIGITS:
0 or 1 for if digit is activated
A
A
B
B
C
10 minus C
temp
temp2
digit as char
Empty
Empty



go to start
while (has more digits) {
3   b = a
5   a = c
8   c = a plus b
   if c exceeds 10 during addition then activate next digit and increase it by 1
}


Use countdown
[
$ assert hasName('countdown')
->>>>>
[ For each activated digit
$ assert hasName('digitStart')
    >>> >>>[-]+++++ +++++
    $ name '10minusC'
    <<<
    $ name 'B'
    [-] Clear B
    <    < [->+>+<<] at A after B = A
    $ name 'A'
    >>>>[->>>>-<<<< <<<<+>>>>] Set A = C and stop at C
    $ name 'C'

    Now do C = A plus B
    <
    $ name 'overflow'
<<
    $ name 'A_2'


     customRun('31')
    [
$ assert hasName('A_2')
->>>+>-
>+<[>-]>[<
code2 <<   +>> +++++ +++++
>->]<<
      <<<<] C = B
    <


    [
$ assert hasName('A')
->+>>>+>- Move 1 from A to the current C value  

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

    >>>
    $ assert hasName('overflow')
    [
        increase next digit and activate it if it wasn't activated already
        >>>>>>>

        Check if next digit was not previously activated

        $ name 'activatedTemp'
          +
        $ name 'activatedTemp2'
          >[<-]<[>
            Activate Digit
            >>> >>> +++++ +++++
            >>> +++++ +++++ +++++ +++++ +++++ +++++ +++++ +++++ +++++ +++
            $ name 'digit'
            <<<
            <<< <<<
            End Activate digit
        <-<]>>
        End check if next digit was not previously activated
        $ name 'digitStart'
        [-]+ > +
        <<<< <<
        End increase next digit
        <<----- ----- <-
    ] C plus equals A
    $ assert hasName('overflow')
    <<
    [-<+>] Move right of A back to A

    Move C to number
    >>> [->>+>>+<<<<] >> [-<<+>>]

Goto next activated digits
>>>>>

] End of all activated digits

Print numbers
<<<

Go back and print numbers
[
$ assert hasName('digit')
. <<<<< <<<< <<<]

Print new line
<.

No more numbers to print now go to the counter
<
]
$ assert hasName('countdown')  

If you want to run this code I’d recommend running it with latest released version of Brainduck. Here’s a screenshot of running it in Brainduck:

Fibonnaci code running in Brainduck

Also, a minified typical BF-version of the code:

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

One Answer

EDIT: Takes 10 minutes to learn BF -- and I didn't realize it was so simple.

  1. Is this readable and understandable?
  2. Does my use of the $-lines makes sense?
  3. Does it help to understand the code?
  4. Can it be even more optimized somehow?

Your assert messages are a little strange for me, but I poke fun at how the Spring Framework checks it's own private values to be null and throwing an exception if they are (for the user to handle).

The 100, 200, and 250 could easily be read to 10, 20, 25 and multiply by 10 on the countdown loop.

Write out the first ones but then having the $name 'zero' is unclear because you're on 48/49 -- it's unclear which 'zero' you're referring to. Because you're already printed out (yes your pointer is on zero again but I see a one).

0
1

Digit 1 Value X is fine and it's easy enough to scale. Though I would use "One's place for value X" instead.

The extra increments before and after `$name 'digitStart' are also "what did he do here, and why?"

After taking the time to read how BF works, the "Set A = C and stop at C" is still confusing.

I would also move your Groovy declarations to before the assignment instead of after

$ name 'X'
> +

for example. As a reader that goes line by line, seeing B = A before A has been declared to be something is weird.

Your actual printing out and calculation loop is clever. I was trying to find how you tested if the value got above 9 for the longest time.

Leaving this even though it's completely unneeded and unrelated at this point in case someone wants it. Just for ridiculous reference, this is the one's place repeating sequence. (Length of 60)

0, 1, 1, 2, 3, 5, 8, 3, 1, 4, 5, 9, 4, 3, 7, 0, 7, 7, 4, 1, 5, 6, 1, 7, 8, 5, 3, 8, 1, 9, 0, 9, 9, 8, 7, 5, 2, 7, 9, 6, 5, 1, 6, 7, 3, 0, 3, 3, 6, 9, 5, 4, 9, 3, 2, 5, 7, 2, 9, 1

Answered by David Fisher on January 2, 2022

Add your own answers!

Related Questions

3-SAT Solver Python

2  Asked on December 12, 2020 by n00bster

       

Operations on nested data

1  Asked on December 11, 2020 by kluvin

       

Library Management System OOP with c++( Part2 of a series )

2  Asked on December 10, 2020 by theprogrammer

   

A Python Blackjack terminal based game

1  Asked on December 8, 2020 by fames

       

Monte carlo simulation in C

1  Asked on December 8, 2020 by kartik-chhajed

     

Hangman Game in Python-3

1  Asked on December 7, 2020 by phinn-galactica

       

Simple parser using Flex and C++

2  Asked on December 5, 2020

       

PHP array with array value into multiple arrays with same key

1  Asked on December 1, 2020 by robert-wilde

 

Wi-fi scheduler written in C

2  Asked on November 30, 2020 by nnncomplex

         

Border Radius in OpenGL

0  Asked on November 28, 2020 by michaelsnowden

 

Does this SASS make sense?

1  Asked on November 16, 2020 by neil-meyer

 

Ensuring if an object is Assignable from a class type

1  Asked on October 28, 2020 by sourabh

   

Mergesort in python

1  Asked on October 28, 2020 by nishil-patel

         

Selection Sort Java and Analysis

1  Asked on October 24, 2020 by gss

     

Computing on two colums

0  Asked on October 24, 2020 by ajayramesh

   

A* using a Priority Queue

0  Asked on October 17, 2020 by ryan-swann

       

Generic solution to Hibernate’s CriteriaQuery

1  Asked on September 23, 2020 by stefan-georgiev-uzunov

       

Checking if a string contains all unique characters

2  Asked on September 11, 2020 by e-setprimeepsilon

     

Ask a Question

Get help from others!

© 2023 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP