Brainfuck详解

tiger2005

2018-08-08 21:09:11

Tech. & Eng.

详解哥再度来袭~(前面出过SPJ详解)

你有没有玩过NazoGame呢

是不是觉得第19关很和谐?

看看地址,哎,怎么写着

brainfuck?

这便是我们今天要讨论的东东

实际上,Brainfuck是一种极小化的计算机语言,它是由Urban Müller在1993年创建的。由于fuck在英语中是脏话,这种语言有时被称为brainf*ck或brainf**k,甚至被简称为BF。

这就是一个语言,但它不像C++那么多元化,但难度也一定的增加,因为

它只有8种关键字!

虽然还有一些更特殊的语言,chicken只有一个关键字chicken。Whitespace由空格、Tab、回车组成,所以全是白的。

但Brainfuck语言可以和图灵机互相模拟

图灵机就是一个模拟数学计算机器人

接下来,就看看这8个关键字有什么用。

基本操作

我们可以假想

Brainfuck开了一个近乎无限长的数组,大小1byte,一个指针指向一个位置

指针操作

>  指针右移一位指向下一个字节
<  指针左移一位指向上一个字节
由于指针两边不会无限长,所以会出现溢出空间的情况,编译器会报错。

字节操作

+  当前指针指向的字节+1
-  当前指针指向的字节-1

当然,一个byte只能存256个数,Brainfuck选择存储0-255,但Brainfuck有一种很玄学的东西
0-1=255
255+1=0
也就是说它自动模256···

读写操作

.  以char的形式输出当前指针指向的字节(48会输出'0')
,  以ASCII的形式读入到当前指针指向的字节(读入'0'会存储48)

getch的回车10会变为换行13,打编译器时要注意了。

循环操作

[  当当前指针指向的字节不是零时,会进行循环
]  当当前指针指向的字节非零时回到循环,否则退出

正确的代码中,所有的循环符号将会分组,两个循环只有分离和包含关系。上面所说的‘循环’就是分组后的循环

所以,8个字符可以与C++转化,这个自己研究去

实例

符号介绍完了,来道小题试试

,----------[----------------------.,----------]

翻译一下?

首先,读入一个字符并减去10
之后,当这个字节非0时循环
循环中将字节减去22输出后重新读入,之后减去10
当它还不是0时继续循环
当它是0时结束循环
什么意思呢
就是将小写字母转大写啦~
回车结束啦~

常用算法

加减算法

如何将一个字节减48?

最直接的就是48个 - 了

但想一想啊

48=6*8

你可以将下一个字节加上6(保证它是0哦)之后打一个循环

当它非0时往左移一位减去8后挪回来减1就行啦~

代码如下

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

复制算法

想想怎么将一个字节上的数挪到下一个字节呢?

[>+<-]

但你会发现原来那个数字没了!qДq

怎么办呢?

先将这个数复制到另一个地方再同时复制

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

第一个循环将这个数复制到后两位

第二个循环将后两位上的数同时复制到原先那一位和其后面的一位

清零算法

清零?

[-]

不用解释了吧~剩下的就自己去摸索和训练吧

BF 的特点

当然 Brainfuck还是有一些好处和坏处的

实际应用

拿一道题做例子(下面有提交地址的哦)

小鱼的游泳时间

这道题的读入有两位数,这正好是一个byte能存下来的
但需要输入处理
先读入一个数,减去48
判断下一个字符是否为空格
若不是,赶紧将前一位乘10啊啊啊
之后就是相加啦~

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

但!负数怎么处理呢

首先我们知道,这个负数不会小于-60,所以可以将其加60后进行60整数除法。若结果为1就表明不用处理否则时数减1

思路就是这样,除法代码暂不给出

彩蛋

编译器(本人的)

P1000的Brainfuck

P1425的Brainfuck

P1427的Brainfuck

P1914的Brainfuck

提交时记得末尾回车哦