Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate the sum of 2 numbers with BrainFuck

Tags:

brainfuck

I'm trying to write a program with BrainFuck that can read two numbers up to 9, calculate the sum of them and then print the result out, e.g. 3 & 5 give the result 8 .

I'm just trying to understand the BF language but it looks much harder than I thought it would be.

like image 982
Yahoo Avatar asked May 20 '12 03:05

Yahoo


3 Answers

I saw this post 2-3 days ago and I've worked on it and now I have a solution on multi-digit addition. First I thought the name of this PL is a bit offensive but now I know, if I was authorized to name this programming language, I'd choose the same.

Now, I'll tell you how to use my code.

$ bf sum.bf
199+997=
1196
$

Only +ve numbers can be added in my code. And make sure you use the same number of digits in both inputs. i.e. if you want to add 57 with 3, then give input like 57+03= or 03+57= . Now the code. I've documented with an example. Still I prefer NOT to look into my code, as designing by yourself is easier than studying or troubleshooting a code in bf. First you need to know how to compare two numbers. My answer in this question is one solution. In documentation, I used 'plus' instead of + ,as + is a valid operation in bf.

    >> +
    [- >,>+< 
    ----- ----- ----- -----    ; checking with ascii 43 ie plus symbol
    ----- ----- ----- -----
    ---
    [
    +++++ +++++ +++++ +++++
    +++++ +++++ +++++ +++++
    +++
    < ] >>
    ]
    ; first input is over and terminated by a 'plus' symbol
    <->>>>>+
    [- >,>+<
    ----- ----- ----- -----   ; checking with ascii 61 ie = symbol
    ----- ----- ----- -----
    ----- ----- ----- ------
    [
    +++++ +++++ +++++ +++++
    +++++ +++++ +++++ +++++
    +++++ +++++ +++++ ++++++
    < ] >>
    ]
        ; second input is over and terminated by an = symbol
        ; now the array looks like 0 0 0 49 0 50 0 0 0 0 0 0 0 0 49 0 53 0 0 1 0
        ; for an input 12'plus'15=
    <<<<
    [<+<]
                ; filled with 1's in between
    + [<+>-<<[>-]>] ; This is a special loop to traverse LEFT through indefinite no of 0s
                ; Lets call it left traverse
    <<
    [<+<]
    >[>]<
               ; now the array looks like
               ; 0 0 1 49 1 50 0 0 0 0 0 0 0 1 49 1 53 0 0 1 for eg:12plus15
    [
    [->+>   + [>+<->>[<-]<]  ; Right traverse
        >>[>]<+ [<]
        + [<+>-<<[>-]>]  ; Left traverse
        <<-<
    ] 
    + [>+<->>[<-]<] 
    >> [>] <<-<[<]
    + [<+>-<<[>-]>]
    <<-<
    ]
             ; now actual addition took place
             ; ie array is 00000000000000 98 0 103 0 0 1
    + [>+<->>[<-]<]
    >>
    [ 
    ----- ----- ----- -----
    ----- ----- ----- -----
    ----- ---
    >>]
                ; minus 48 to get the addition correct as we add 2 ascii numbers
    >-<         ; well an undesired 1 was there 2 place after 103 right ? just to kill it
            ; now the array is 00000 00000 0000 50 0 55
            ; now comes the biggest task Carry shifting
    <<
    [<<]
    +++++ +++++ +++++ +++++
    +++++ +++++ +++++ +++++
    +++++ +++
    [>>]
        ; we added a 48 before all the digits in case there is an overall carry
        ; to make the size n plus 1
        ; array : 00000 00000 00 48 0 50 0 55
    <<
    <<
    [
    [>>->[>]>+>>>> >>>+<<<< <<<<<[<]><<]
    >+[>]>-
    [-<<[<]>+[>]>]
    >>>>>+>>>
    +++++ +++++ +++++ +++++ +++++
    +++++ +++++ +++++ +++++ +++++
    +++++ +++
    <
                ; comparison loop:  0   1   0   a      b  0
                ;                  (q) (p)    (num)  (58)
    [->-[>]<<]  ; comparison loop to check each digit with 58: greater means 
                ; we need to minus 10 and add 1 to next significant digit
    <[-
            ; n greater than or equal to 58 (at p)
            <<<< <<<
            [<]+
            >
            ----- ----- ; minus 10 to that digit
            <<+         ; plus 1 to next digit
            >
            [>]
            >>>>>>
    ]
    < [-<
            ; n less than 58 (at q)
            <<<<<<
            [<]+
            [>]
            >>>>>
      ]
        ; at (q)
        >>>[-]>[-]
        <<<<< <<<<<
        [<]>
        <<
    ]
        ; Its all over now : something like 0 48 0 52 0 66 ( ie 0 4 18 )
        ; will turn into 0 48 0 53 0 56 (ie 0 5 8)
    >>
    ----- ----- ----- -----
    ----- ----- ----- -----
    ----- ---
            ; here we are just checking first digit is 48 or not
            ; its weird to print 0 ahead but it is defenitely needed
            ; if it is 49 ie 1
    [
    +++++ +++++ +++++ +++++
    +++++ +++++ +++++ +++++
    +++++ +++
    .
    [-]
    ]
    >>
    [.>>]
    +++++ +++++
    .           ; to print nextline : ascii 10

I know its a bit lengthy code, may be there are better solutions possible. But still it worth a shot.

like image 175
Dheeraj Ram Avatar answered Nov 05 '22 16:11

Dheeraj Ram


Think of the language as a huge tape (30K bytes long) where you can read, write and move forward or backward and increment/decrement one cell at a time (each cell being 1 byte, so you effectively have 30K cells). Optionally, you can read in and write out stuff that the byte stream holds(in ASCII form). Assuming that you know the basic operators, a program to sum two numbers should go along the following lines:

,       ; read character and store it in p1
>       ; move pointer to p2 (second byte)
,       ; read character and store it in p2
[           ; enter loop
    <       ; move to p1
    +       ; increment p1
    >       ; move to p2
    -       ; decrement p2
]           ; we exit the loop when the last cell is empty
<       ; go back to p1
------------------------------------------------ ; subtract 48 (ie ASCII char code of '0')
.       ; print p1
like image 34
dirkgently Avatar answered Nov 05 '22 17:11

dirkgently


That is what I know

,                           ;read character and store it in p1
------------------------------------------------   ;return ascii to Dec
<                           ;move pointer to p2 (second byte)
,                           ;read character and store it in p2
------------------------------------------------ ;return ascii to Dec
[                           ; enter loop
-                           ; decrement p2
>                           ; move to p1
+                           ; increment p1
<                           ; move to p2
]                           ; we exit the loop when the last cell is empty
>                           ;go back to p1
++++++++++++++++++++++++++++++++++++++++++++++++     ;return Dec to ascii
.                           ;print p1

input:

12

output:

3

You should use numbers under 10 and that result under 10

like image 3
mikel Avatar answered Nov 05 '22 16:11

mikel