2012-05-20 72 views
6

我想寫與BrainFuck一個程序,可以讀出兩個數高達9,計算它們的總和,然後打印出結果,如3 & 5給出結果8。如何計算兩個數字的總和與BrainFuck

我只是想了解BF語言,但它看起來比我想象的要困難得多。

回答

27

認爲語言是一個巨大的膠帶(30K字節),在那裏你可以讀,寫,向前或向後移動和增量/在一個時間遞減一個單元(每個單元爲1個字節,所以你有效地具有30K細胞)。或者,您可以讀入和寫出字節流保存的內容(以ASCII形式)。假設你知道基本的運營商,程序總結兩個數字應該大致如下走:

,  ; 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 
+0

非常感謝。這對我現在確實有意義。 – Yahoo

+2

我經歷了一遍又一遍的代碼後,我意識到它只能用於單個值。right!我的意思是,如果結果是單值例如3 + 2 = 5就沒問題,但如果我們有類似4 + 6 = 10的東西,那麼情況會怎樣呢? – Yahoo

+0

@Yahoo:是的,那是真的。這僅僅是一個例子。但是你總是可以擴展它以處理大於9的值。另外,請記住,打印一個多位數字本身需要一些思考,因爲你需要實現'n' putchars,其中'n'是位數總和。 – dirkgently

9

我看到這個帖子2-3天前,我已經在它的工作,現在我有一個解決方案多位數加法。首先,我認爲這個PL的名字有點冒犯,但現在我知道,如果我被授權命名這種編程語言,我會選擇相同的。現在

,我會告訴你如何使用我的代碼

$ bf sum.bf 
199+997= 
1196 
$ 

只有+ ve號碼可以在我的代碼中添加。並且請確保您在兩個輸入中使用相同的數字位數。即如果你想用3加57,那麼給出57 + 03 =或03 + 57 =等輸入。 現在的代碼。我用一個例子記錄下來。儘管如此,我還是不想看看自己的代碼,因爲自己設計比學習或解決bf中的代碼更容易。首先你需要知道如何比較兩個數字。我在this問題的答案是一個解決方案。 在文檔中,我使用'plus'而不是+,因爲+是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 

我知道它有點冗長的代碼,可能是有可能更好的解決方案。 但它仍值得一試。

3

這是我知道的

,       ;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 

輸入:

12 

輸出:

3 

你應該在10使用數字和結果在10

+0

你的'<'在結束循環之前說';移動到p1',它應該是'搬到p2' – Goodwine

+0

非常感謝,我很抱歉。 – mikel

+0

無需道歉,您的答案很棒! :) – Goodwine

0

我也做了一個程序,只能處理單個數字輸入和解答:如果你想要得到的結果與一個以上的數字

#Make the first cell (Cell 0) hold a value of 48 
>++++ ++++ 
[ 
<++++ ++ 
>- 
] 

#Get inputs and minus 48 from each to get Decimal 

,>, 
<< 
[ 
>- 
>- 
<<- 
] 

#Adds the contents of Cells 1 and 2 


> 
[ 
>+ 
<- 
] 

#Moves answer to Cell 0 
> 
[ 
<+ 
>- 
] 
< 
[ 
<+ 
>- 
] 

#Converts answer to ASCII 
>++++ ++++ 
[ 
<++++ ++ 
>- 
] 
< 

[ 
<+ 
>- 
] 
< 
#Print answer 
. 
0

,你有你的brainfuck-使用十進制轉換器碼。其餘的是正常的計算:

,       writing input char in cell(0) 
    >,       writing input char in cell(1) 
    >>++++++++[<++++++>-]  writing 48/0x30/ASCII('0') in cell(2) 
    <       go to cell(2) 
    [-<-<->>]     subtract cell(2) from cell(1) and cell(2) 
    <       go to cell(1) 
    [<+>-]      calculating the sum 
           cell(0) = cell(0) plus cell(1); cell(1) = 0 
    <       go to cell(0) 


    >[-]++++++++[>[-]<[->+<]>-]<<<<<<<<< here begins the converter code 
    this first line sets all cells between cell(1) and cell(9) to 0 (including!) 

    [->+<]>     moving cell(0) to cell(1) 
    [>+<-<+>]>    moving cell(1) to cell(0) and cell(2) 
          this ends up in copying cell(0) to cell(2) 
    [      here begins a complex loop 
          it doesn't end at the same cell as it starts 
     >>>>> 
     [->+<] 
     > 
     + 
     <<<<< 
     ++++++++++ 
     < 
     [ 
      - 
      >> 
      + 
      < 
      - 
      [>>>] 
      > 
      [ 
       [<+>-] 
       > 
       + 
       >> 
      ] 
      <<<<< 
     ] 
     > 
     [-] 
     > 
     [-<<+>>] 
     > 
     [-<<+>>] 
     << 
    ] 
    >>>>> 
    [      this is the output loop 
          it also doesn't end at the same cell as it starts 
     <<<< 
     +++++++ 
     [-<+++++++>] 
     < 
     - 
     [<+>-] 
     < 
     . 
     [-] 
     >>>>>> 
     [-<+>] 
     < 
     - 
    ] 
    <<<<<<<     this probably sets the pointer to 0 
          but I don't know if there are still values in some cells 

可悲的是我不得不說,我不明白整個轉換器代碼,雖然我真的嘗試過。我只是從德國維基百科網站複製它。也許有人可以解釋它?:)