欢迎来到飞鸟慕鱼博客,开始您的技术之旅!
当前位置: 首页知识笔记正文

Python实现BrainFxxk虚拟机

墨初 知识笔记 94阅读
Python实现BrainFxxk虚拟机




文章目录 Python实现BrainFxxk虚拟机‍前言什么是BrainFxxk‍内容一BrainFxxk的字符标识‍⚖️内容二经典案例——打印 Hello World‍内容三BrainFxxk编程中的加减乘除文末推荐【3D科研绘图 · 与学术图表绘制从入门到精通】


‍前言什么是BrainFxxk


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

Müller的目标是建立一种简单的、可以用最小的编译器来实现的、符合图灵完全思想的编程语言。这种语言由八种状态构成为Amiga机器编写的编译器第二版只有240个字节大小
就象它的名字所暗示的brainfuck程序很难读懂。尽管如此brainfuck图灵机一样可以完成任何计算任务。虽然brainfuck的计算方式如此与众不同但它确实能够正确运行。
这种语言基于一个简单的机器模型除了指令这个机器还包括一个以字节为单位、被初始化为零的数组、一个指向该数组的指针初始时指向数组的第一个字节、以及用于输入输出的两个字节流。
这种语言是一种按照“Turing complete图灵完备”思想设计的语言它的主要设计思路是用最小的概念实现一种“简单”的语言BrainF**k 语言只有八种符号所有的操作都由这八种符号的组合来完成。


‍内容一BrainFxxk的字符标识

Brainfuck基于这样一台机器。它具有一列初始化为0的数组数组长度最初要求是30,000但这个标准不是必要的和一个初始指向第一个元素的指针。
❤️该语言总共只有8个命令除此之外所有其他字符都会被忽略
><-.,[]

下面是这八种状态的描述其中每个状态由一个字符标识


‍⚖️内容二经典案例——打印 Hello World

了解了关于BrainFuck的一些基本知识接下来我们试着输出 Hello World

1️⃣首先如何用BF换行

需要注意的是BF标准规定换行符使用’\n’(10)而非’\r’(13)所以现在我们需要输出一个10。我们使用和.两个命令

.
这样我们就成功换行。

2️⃣但接着问题就来了如果我要打印一个’A’(65)怎么办写65个估计这样的话键盘磨损很快吧当然如果你用程序输出程序当我没说
这种时候我们就需要使用乘法了。658*81而乘法可以使用循环写我们再引入其他几个命令。
[><-]>.
看这个程序其先将当前位置加8然后循环运行右移加8左移减1直到左侧单元为0然后右移加1就获得了65。这实际上就是将8加8次然后加1。用类似的方法可以大大压缩程序大小。

有了这些知识储备我们就可以写一个输出Hello, World!的程序了
[><-]>.>>[<>-]<....>>[<>-]<.------------.<<<[><-]>.>..------.--------.>.(147)
括号里就是整个程序的长度如你所见这是很简单的。

为了方便大家理解我将分析过程也放在下面了

1.   将 *ptr0 置为 10用作后面循环的条件。2.  [>>>><<<<-] 循环 10 次每次执行*(ptr0  1)  7*(ptr0  2)  10*(ptr0  3)  3*(ptr0  4)  1当循环完后*(ptr0  1)  70*(ptr0  2)  100*(ptr0  3)  30*(ptr0  4)  103.  >.>....>.<<.>..------.--------.>.>. 这一串就是通过加减得到每个字母对应的 ascii 码然后将其打印出来大致过程如下初始值:*(ptr0  1)  70*(ptr0  2)  100*(ptr0  3)  30*(ptr0  4)  10代码计算过程*(ptr0  1)  72 输出 H*(ptr0  2)  101 输出 e*(ptr0  2)  108 输出 l*(ptr0  2)  108 输出 l*(ptr0  2)   111 输出 o*(ptr0  3)  32 输出  *(ptr0  1)  87 输出 W*(ptr0  2)   111 输出 o*(ptr0  2)   114 输出 r*(ptr0  2)   108 输出 l*(ptr0  2)   100 输出 d*(ptr0  3)  33 输出 !*(ptr0  4)  10 输出 \n

3️⃣最后我们使用Python来模拟这个过程【代码如下】

import sysdef mtd(code):    data  [0 for i in range(1000)]    pc  0    ptr  0    skip_loop  False    bracket_count  0    stack  []    while pc < len(code):        c  code[pc]        if skip_loop :            if c [:                bracket_count1            elif c]:                bracket_count -1                if bracket_count0:                    skip_loop False            pc1            continue        if c  >:            ptr 1            pc 1        elif c  <:            ptr -1            pc 1        elif c  :            data[ptr] 1            pc 1        elif c  -:            data[ptr] -1            pc 1        elif c  .:            print(chr(data[ptr]),end)            pc 1        elif c  ,:            pc 1        elif c  [:            if data[ptr]  0:                #nonlocal bracket_count,skip_loop                bracket_count  1                skip_loop  True                pc1            else:                pc1                stack.append(pc)        elif c  ]:            if data[ptr]  0:                pc1                stack.pop()            else:                pc  stack[len(stack)-1]code  input(请输入一串代码)mtd(code)

让我们把上述的代码导入看看是什么样的结果吧

很明显我们已经成功做到了


‍内容三BrainFxxk编程中的加减乘除
1. x0x[-]我们只需要把变量循环减到0就好了2. xyx[-]tmp[-]y[xtmpy-]tmp[ytmp-]x我们可以设置一个中间变量tmp把y同时复制到x和tmp再把tmp复制回y。3. xytmp[-]y[xtmpy-]tmp[ytmp-]x只需要把xy中的清空x变量删去即可。那么xyz怎么办我们可以分别运行xyxz。这样我们就获得了结果。4. x-ytmp[-]y[x-tmpy-]tmp[ytmp-]x类似xy不解释5.x*yx*y可以写作y个x相加我们可以使用上述for循环即for(tmpx,x0;tmp;--tmp){    xy;}翻译一下即得tmp0[-]tmp1[-]x[tmp1x-]tmp1[y[tmp0xy-]tmp0[ytmp0-]tmp1-]x6. x/ytmp0x,x0;tmp10;while(tmp0){    for(tmp1y;tmp1;--tmp1){        --tmp0;        if(tmp00){            --tmp1;            if(tmp1){        //如果tmp00时tmp1!0说明没有整除x要减掉一个后面多加的1                --x;                tmp10;            }            tmp1;        }    }    x;}翻译后tmp0[-]tmp1[-]tmp2[-]tmp3[-]x[tmp0x-]tmp0[y[tmp1tmp2y-]tmp2[ytmp2-]tmp1[tmp2tmp0-[tmp2-tmp0[tmp3tmp0-]]tmp3[tmp0tmp3-]tmp2[tmp1-[x-tmp1[-]]tmp2[-]]tmp1-]xtmp0]x

因此我们可以在上述代码的基础上改写一个减法虚拟机

import sysdef mtd(x,y,code):    data  [0 for i in range(1000)]    data[0]  int(x)    data[1]  int(y)    if(data[0]<data[1]):        t  0;        t  data[0]        data[0]  data[1]        data[1]  t    pc  0    ptr  0    skip_loop  False    bracket_count  0    stack  []    while pc < len(code):        c  code[pc]        if skip_loop :            if c [:                bracket_count1            elif c]:                bracket_count -1                if bracket_count0:                    skip_loop False            pc1            continue        if c  >:            ptr 1            pc 1        elif c  <:            ptr -1            pc 1        elif c  :            data[ptr] 1            pc 1        elif c  -:            data[ptr] -1            pc 1        elif c  .:            print(chr(data[ptr]),end)            pc 1        elif c  ,:            pc 1        elif c  [:            if data[ptr]  0:                #nonlocal bracket_count,skip_loop                bracket_count  1                skip_loop  True                pc1            else:                pc1                stack.append(pc)        elif c  ]:            if data[ptr]  0:                pc1                stack.pop()            else:                pc  stack[len(stack)-1]    print((data[0]), end)x  input(请输入数字一)y  input(请输入数字二)code  >>[-]<[<->><-]>[<>-]<<   ## xx-ymtd(x,y,code)

运行一下发现确实实现了想要的效果


文末推荐【3D科研绘图 · 与学术图表绘制从入门到精通】

书籍介绍
本期为大家带来的是北京大学出版社的《3D科研绘图 · 与学术图表绘制从入门到精通》
本书共7章系统讲解了化学、材料学、生物医学等领域的作图需求和相关软件技术并从设计基本概念、软件底层原理和案例实际操作三个方面展开全方位的教学。
本书在内容的设定和案例的选择上充分考虑了读者对象的需求无论是刚入门的初学者还是寻求深度发展的科学可视化人员都能从中汲取所需的知识。特别是涉及专业科学可视化部分的内容有效填补了现有同类型参考书的空白。本书专为有图像设计需求的研究人员和科学可视化从业者编写。


‍♂️本书特色
1.实例丰富我们涵盖各类绘图软件与工具让你能够自如运用不同技术绘制出高质量的图表。
2.内容全面全流程讲解3D科研绘图与学术图表绘制的方法有效填补了现有同类型参考书的空白。
3.经验总结作者多年一线研发实战经验全面归纳整理毫无保留分享技术要领。
4.大咖力荐多位大型科技公司技术高管和高校相关领域教研专家推荐。
5.全彩印刷图表案例精彩呈现带来良好的阅读体验方便理解和学习。

‍♂️作者介绍
李浩东复旦大学高分子专业博士国内最大的3D科研绘图微信公众号“3D科研绘图”主笔杭州思斐迩科技有限公司联合创始人之一、设计总监。曾为全球上百家高校和科研机构提供设计服务包括中科院、清华、北大、MIT、Stanford、ETHZurich、EPFL等设计作品被Science、Nature、JACS、Angew等知名期刊选用。目前已为浙江大学、同济大学、上海科技大学、武汉大学、中科院大连化物所、山西煤化所、青岛生物能源所等单位提供专业绘图讲座和培训线上线下总受众数超十万人。

参与形式
关注➕点赞➕收藏➕评论每人最多可以评论三条随机抽取2位小伙伴免费送书一本

抽奖时间
⏰2023-11-04 18:00

标签:
声明:无特别说明,转载请标明本文来源!