首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >验证Brainfuck程序

验证Brainfuck程序
EN

Code Golf用户
提问于 2014-01-03 17:16:40
回答 9查看 3.6K关注 0票数 20

另一个Brainfuck解析问题,但这次..。不一样。

您正在无限猴子公司工作,该公司正在制作Brainfuck程序,以解决各种有趣的问题(这是偶然的,毕竟,公司会制作随机程序)。然而,看来您只执行Brainfuck的快速图灵机器在语法错误方面有一个小而昂贵的问题--做一个错误,计算机就会爆炸。这可能是一个设计缺陷,但没有人费心去找出它发生的原因。由于图灵机器(特别是快速机器)是昂贵的(毕竟,它们有无穷大的RAM,因此在执行代码之前最好确保程序没有任何语法错误。您的公司将运行大量代码,因此手动验证无法工作。编写一个读取Brainfuck代码的STDIN的程序,如果程序有任何语法错误(例如,]是语法错误,因为没有匹配的[),则退出状态设置为0(错误)。退出状态设置为0,如果程序是完全好的。确保您的程序正确地注意到涉及[]的错误。你不会想让另一台电脑爆炸吧?哦,并且确保它尽可能短--你的老板为短期项目买单(因为他认为它们很快,或者其他什么的)。哦,而且你不必用Brainfuck来编码(事实上,你不能,因为Brainfuck不支持退出代码)--你的代码将在普通计算机上运行。

因此,正如您所看到的,您的工作是检查Brainfuck程序是否“有效”(有配对的[]符号)。请注意,Brainfuck程序可以有[]以外的其他字符,所以不要仅仅因为程序有其他命令就拒绝它。最小的代码赢了,但是无论如何你可能会更关心向上的代码。

EN

回答 9

Code Golf用户

回答已采纳

发布于 2014-01-03 22:44:21

GolfScript,18 chars

代码语言:javascript
复制
.{[]`?)},~](`91?./

如果输入中的方括号是平衡的,此代码将成功地运行退出代码0(并将一些垃圾输出到stdout)。如果它们不是,则在非零退出代码中失败,并将错误消息打印到stderr,例如:

代码语言:javascript
复制
(eval):2:in `/': divided by 0 (ZeroDivisionError)

代码语言:javascript
复制
(eval):1:in `initialize': undefined method `ginspect' for nil:NilClass (NoMethodError)

由于挑战没有提到stdout / stderr的输出,所以我认为这是合格的。在任何情况下,您都可以将这些重定向到/dev/null

解释:

代码{[]`?)},从输入中剥离除方括号以外的所有内容,~将结果计算为GolfScript代码。棘手的部分是不平衡的括号在GolfScript中是完全合法的(实际上,我的代码包括一个!),所以我们需要一些其他的方法来使代码崩溃。

我使用的技巧是在堆栈底部保留输入的副本,将整个堆栈收集到一个数组中(使用不平衡的]),并将第一个元素移开。在这一点上,有三件事可以发生:

  • 如果输入以未关闭的[结尾,尝试将一个元素从空数组中移出将导致解释器崩溃(在本例中,这正是我们想要的!)
  • 如果输入中的括号是平衡的,则移位元素将是原始输入字符串。
  • 否则(如果输入有未打开的]或未关闭的[),它将是一个数组。

然后,我最初的14 char条目将移位值与字符串进行比较,如果它是嵌套数组,则字符串会崩溃。不幸的是,在GolfScript中,将平面数组(特别是空数组)与字符串进行比较也是合法的,因此我不得不切换tack。

相反,我当前提交的文件使用了一种非常强力的方法来区分数组和字符串:它对数组进行反求,并试图找到[ (ASCII代码91)的第一次出现,只有当未评估的变量是数组时,它才是零。如果是这样的话,用自身除以零就会触发所需的崩溃。

Ps。另外两种18-char解决方案是:

代码语言:javascript
复制
.{[]`?)},{.}%~](n<

代码语言:javascript
复制
.{[]`?)},~]([n]+n<

唉,我还没有找到一个更短的方法来解决“空数组问题”。

票数 6
EN

Code Golf用户

发布于 2014-01-03 17:36:51

bash (tr + sed) - 42

代码语言:javascript
复制
[ -z `tr -Cd []|sed ":a;s/\[\]//g;t a"` ]

如果您不介意错误消息,那么您可以删除`]之间的最后一个空格来获得长度41。

票数 4
EN

Code Golf用户

发布于 2014-01-04 01:38:28

Haskell (143)

代码语言:javascript
复制
import System.Exit
f=exitFailure
v c []|c==0=exitSuccess|True=f
v c (s:t)|c<0=f|s=='['=v(c+1)t|s==']'=v(c-1)t|True=v c t
main=getContents>>=v 0

对jgon:使用2个守卫似乎比如果-然后-其他更密集。而且,我不认为你的检查括号是按照正确的顺序("][“通行证)

票数 3
EN
页面原文内容由Code Golf提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codegolf.stackexchange.com/questions/17342

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档