如何在 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
-]+
我刚刚发现了一种编程语言,叫做 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
-]+