您的位置:首页 > Web前端

spoj 1 Life, the Universe, and Everything

2015-08-19 06:38 513 查看
TEST - Life, the Universe, and Everything

Your program is to use the brute-force approach in order to find the Answer to Life, the Universe, and Everything. More precisely… rewrite small numbers from input to output. Stop processing input after reading in the number 42. All numbers at input are integers of one or two digits.

Example

Input:

1

2

88

42

99

Output:

1

2

88

Information

If you have some troubles with your code, you can take a look in the forum, you’ll find the answer, only for this problem, in various languages.

做这道只是一个偶然,作为spoj的第一题,可以说并没有什么难度。之所以做它,是因为偶然看到了Matrix67很多年前的一个帖子,用BrainFuck来解决这个问题。之前就有听过这个编程语言,因为这个名字过目不忘,此外也有听闻linguo大神还曾经在比赛中用它AC过题,所以想看看这到底是个什么玩意。

BrainFuck是一个非常简单直观的语言,介绍参见:https://esolangs.org/wiki/Brainfuck,操作只有六种:

>指针加1

>指针减1

+指针所指向的字节的值加1

-指针所指向的字节的值减1

,输入内容到当前指针指向的字节(以ASCII码形式存储)

. 输出当前指针指向的字节的值(以ASCII码对应的字符形式输出)

[循环的起始处,当前指针指向字节的值不为0,那么就进入循环

]循环的结束处,当前指针指向的字节的值为0,则退出循环,否则返回对应的循环起始处,继续循环。

正因为操作如此简单,那么变成过程就变得繁复,就连比较两个值的大小都变得很麻烦,fuck your brain名副其实。搞了很久,终于AC了。

下面是我的AC代码,

+[+++++++++++++++++++++++++++++++++++++++++
>,>,----------[++++++++++[->+<],[-]]>[-<+>]<

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


初看之下觉得这是什么鸟文啊,但它的确是可以被解释运行的程序,需要说明的是我的程序效率不高,spoj上排名倒数几个,所以可以改进的地方多多。下面我只是扼要解释一下代码,如果真有谁闲得蛋疼要深究细节,那你画个图,按照代码流程走一遍就都清楚了。

+[+++++++++++++++++++++++++++++++++++++++++
>,>,----------[++++++++++[->+<],[-]]>[-<+>]<


外面这个括号是循环用的,因为题目要求读到42就停止,如果没读到42,那么就要一直循环。先加1能够进入循环,然后再加41,然后就把42存在第一个字节了,然后读入两个符号,可能是两个数,也有可能是一个数和一个换行号(ASCII码为10)。如果读入的是两个数,那么就还有一个换行号需要读,所以后面这一段代码做的工作就是判断第二个符号是否是10(即换行号),如果是就把它清0,否则是数字,保留数字,把换行号读进来然后清0. 说起来简单,实现起来可不能这么直接。

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


这一段其实就是完成把一位数和两位数统一起来,例如9和40,假设有两个字节存储输入的数字:对于9,第一个字节是‘9’,第二个字节是0,对于40,第一个字节是‘4’,第二个字节是‘0’(注意这个‘0’是字符,ascii码48,与第一种情况的0不一样),所以我们这段代码做的就是交换一位数的位置,把‘9’放到第二个字节,0放到第一个字节。这样是为了方便后面的计算,此时第二字节都是个位了。

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


这么一段做的是把字符换成数值,例如40,存在内存中是:第一个字节 ‘4’,第二个字节‘0’,经过这一段代码我们把它转化成第一个字节40,第二个字节0,这样的目的是为了下一步把40和42做比较。

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


这一段一开始就是把40和42做比较,然后根据比较结果来确定需不需要输出数字,如果是42,那么就不输出,并且退出循环,如果不是42,那还要看是一位数还是两位数,如果是两位是就要进行两次输出,分别输出十位和个位,而一位数就只需要输出个位,数字输出完毕后,输出一个换行号来换行。最后指针回到第一字节,把它置为1,这样循环就会继续下去,如果是42,那么就会跳过吧第一字节置为1的操作,因此第一字节为0,从而退出循环,程序结束。

在现如今各种语言封装得越来越高级的时候,写下brainfuck反而有种求虐却又返璞归真的感觉。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  brainfuck