在Brainf*ck中处理循环

15

我尝试用Brainfuck编写这个瓶子形状的代码来测试我的C语言解释器:

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

而不是从99到1输出整首“墙上的99瓶啤酒”歌曲,它只输出了从99到96瓶的诗句。这个Brainfuck代码中的循环或解释器有问题吗?

这是我的C代码:

#include <stdio.h>
#include <stdlib.h>

int loop(char *commands, int indexOfCommand, int mode){
    int sum = 0;
    int movingIndex = indexOfCommand;
    while(sum > -1){
        movingIndex -= mode;
        if(commands[movingIndex] == ']') 
            sum += mode;
        else if(commands[movingIndex]=='[')
            sum -= mode;
    }
    return movingIndex;
}

int main(){
    unsigned char array[30000] = {0}; // all elements are 0
    unsigned char commands[60000] = {0}; // all elements are 0
    int counter = 0;
    int c;

    int loop(char *commands, int indexOfCommand, int mode);

    while((c = getchar()) != EOF){
        commands[counter] = c;
        counter++;
    }   

    int indexOfArray = counter;
    int indexOfCommands = 0;
    int numOfCommands = 0;

    int length = sizeof(commands)/sizeof(commands[0]); // the length of an array

    while (indexOfCommands < length && numOfCommands < 60000){
        switch(commands[indexOfCommands]){
            case '+':
                if(array[indexOfArray]==255){
                    array[indexOfArray]=0;
                } else array[indexOfArray]++;
            break;
            case '-':
                if(array[indexOfArray]==0){
                    array[indexOfArray]=255;
                }else array[indexOfArray]--;
            break;
            case '>':
                indexOfArray++;
            break;
            case '<':
                indexOfArray--;
            break;
            case '.':
                putchar(array[indexOfArray]);
            break;
            case ']':
                if(array[indexOfArray]!=0) {
                    indexOfCommands=loop(commands,indexOfCommands,1);
                }
            break;
            case '[':
                if(array[indexOfArray]==0){
                    indexOfCommands=loop(commands,indexOfCommands,-1);
                }
            break;
            default:
                // if there is any other character, just ignore it
                break;
        }
        indexOfCommands++;
        numOfCommands++;
    }

    return 0;
}

8
喜欢你编程的方式兄弟 :D - yahya el fakir
5
刚刚让我的周末变得更美好了。 - cerkiewny
不得不截屏这个,感谢@lol带来的lolz。 - Dan Beaulieu
你的 int loop(char *commands, int indexOfCommand, int mode); 放错位置了吗? - Thomas Ayoub
@Thomas:我不这么认为。函数声明可以合法地放置在其他函数内部(如果我没记错的话)=) - user3079266
1个回答

6
程序执行过程中的异常终止条件如下:
while (indexOfCommands < length && numOfCommands < 60000) {
                                   ^^^^^^^^^^^^^^^^^^^^^
    // interpret BF opcodes

    numOfCommands++;
}

您低估了BF程序执行简单任务所需的指令数量。(我不确定为什么会有这个条件。将其删除,您将看到所有99行诗歌。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接