如何在 Brainfuck 中编写 if else 语句

How to write if else statements in Brainfuck

我刚刚发现了一种编程语言,叫做 Brainfuck。

我的问题是如何在 Brainfuck 中编写 if-else 语句?

是通过比较两个单元格完成的吗?如果是,那么我如何比较这个程序中的两个单元格?

谢谢

您需要一个 [x,1] 结构,其中 x 可以是 0 或其他值。解释它的最短方法是创建一个循环,您知道指针不会在它开始的地方结束循环。

假设这些单元格被命名为 cell1 和 cell2

您执行的操作更改了单元格 1 的值,而单元格 2 的值未更改。

操作值后,将指针指向单元格 1,然后执行其他操作。

[-]> cell1 = 0
[-]+ cell2 = 1
|manipulations that change cell1 value
|goto to cell1
[                          // if cell1 != 0
    [-]>[-]                // both cell1 and cell2 now equal 0 
                              if you want the loop to end and want to prevent the 
                              next loop from starting
    |do something
    |goto cell1            // Make sure you point again to cell1 to exit the loop
]>[                        // else
    |do something else
    |goto cell1            // Make sure you point again to cell1 to exit the loop
]

在这个例子中,我使用//来标记评论,我使用|来标记操作。 失去对指针的跟踪是您最大的敌人,因此分离您的代码并添加一些注释可能会有所帮助。


现在!最终回答你的问题:不,你不比较两个单元格,你做的操作要么结果为 0,要么是其他结果,然后 然后 你检查那个单元格是否 == 0.

您执行的操作可以比较两个单元格,但您必须制作自己的序列才能这样做


这里是 Brainfuck 的维基百科页面,在这里您可以看到 Brainfuck 的许多简单和复杂的算法,欢迎来到社区:)

https://esolangs.org/wiki/Brainfuck_algorithms#if_.28x.29_.7B_code1_.7D_else_.7B_code2_.7D

编辑:我在最后 post 中弄乱了 @e 位置;默认情况下应为 1。


感谢@Sirmyself 的回答。但是,有一个问题:如果你这样做

# reimplementation of @Sirmyself's answer, bare
>+
<[
    [-]>-
    # if block
<]>[
    -
    # else block
]

# same as above, address-annotated
@0
>@1 +1
<@0 [
    @0 [-]0  # problem
    >@1 -1
    # if block
<@0 ] >@1 [
    @1 -1
    # else block
@1 ]

然后消耗@0处的值。更重要的是,如果解释器未优化,它会尝试一次减少 @0 处的值,并且需要很长时间才能达到 运行.

更好的方法是使用两个额外的常量 @k@2k 和一个额外的变量 @e,像这样:(我使用 @1 @2 @3,分别)

@0
>@1 [-]0 >@2 [-]+1 >@3 [-]+1
<<<@0 [
    # if block
>>>@3 -1 <<@1 ] >@1|2 [ <@1 ] >>@3 [
    # else block
@3 -1 ] +1

更详细的解释:

@0  # original value
>@1 [-]0 >@2 [-]+1 >@3 [-]+1   # @1 and @2 are constants; (@3)=1 indicates else
<<<@0 [                        # go in from the original value
    # if block
>>>@3 -1 <<@1 ]                # if executes: (@3)=0; (ptr=@1)==0 no loop
>@1|2                          # @1 into @2 (if); @0 into @1 (else)
[ <@1 ]                        # @2 back to (@1)==0 and exits; restabilize at @1
>>@3 [                         # enter block at else flag
    # else block
@3 -1 ] +1                     # reset else flag; exit

请注意,这会保留原始值并且不会冒重复递减值的风险。

重要提示:原始值 @o 和常量 @k@2k 必须在内存中均匀分布,即按地址 @k - @o == @2k - @k。这是滑动和返回工作所必需的。

我看到这个 Stack Overflow 页面是因为我想加快 if-else 的速度,但最终我还是不得不想出自己的解决方案。

用于复制粘贴的裸代码:(我真的推荐地址注释)

>[-]>[-]+>[-]+
<<<[
    # if block
>>>-<<]>[<]>>[
    # else block
-]+