2012-05-20 34 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 

可悲的是我不得不说,我不明白整个转换器代码,虽然我真的尝试过。我只是从德国维基百科网站复制它。也许有人可以解释它?:)