Quine —— 能够自我繁殖的程序生命
声明:本文原创,部分灵感参考于
禁止抄袭。
你是否有过一个念头:“我要写一个能输出自己的程序!”
目的呢,可能是想要挑战、娱乐、炫耀。
但是,经过七七四十九般尝试,你依然没有研究出来这种程序。
不过,看完这篇文章,你就会 Get 到以前让你不敢相信的代码!
那就让我们尝试写一写吧!
提示:我是 C++
党,所以本文的所有代码都是用 C++
编写的。不过,尽管你不会 C++
,只要读懂了思路,稍加变通,我相信你也一定能成功!
Part 1 一次大胆的尝试
首先,凡是代码都有框架:
cout << "...";
然后,我们要将代码里的 ...
替换成整个代码,注意特殊字符的转义:
cout << "cout << \"...\"";
emmm,又出现了一个 ...
,按照规矩,我们应该把它也替换成整个代码。
cout << "cout << \"cout << \"cout << \"...\"\";\"";
emmm,还有一个 ...
,所以继续替换……
等等,你有没有发现什么不对劲的地方?
Part 2 无法打破的 “造物论”
看着上方越来越长的代码,你不禁陷入深思。
照这么写,我的代码要写 INF 列啊!!!QWQ
我们貌似发现了一个无法打破的理论,我们暂且称之为 “造物论”。该理论指出,任何一种物质,都只能由比其跟高级的物质造出。例如,汽车厂造出汽车,人类造出玩具。(我们的程序也可以由 Windows
强大的文件读写特性直接输出代码文件自己,但是过程中利用了 Windows
这种比代码复杂 10000 倍的东西,并没有违背定理。)
所以貌似 “造物论” 开始阻拦我们的实现了。 但是,“造物论” 真的就无法打破吗? 答案是否定的。
Part 3 自我繁殖的奥秘
微生物的繁殖,人类繁衍后代,植物授粉,无一不在做 “造物论” 的反例!大自然,就是我们成功的一丝希望!
举个例子,乌龟的繁殖。(真实画面请自行脑补,以下仅作参考)
程序,也可以用类似的方法进行繁殖。
#include<cstdio>
char s[]="#include<cstdio>%cchar s[]=%c%s%c;%cint main(){printf(s,10,34,s,34);}";
int main(){printf(s,10,34,s,34,10);}
我们可以先输出代码其他部分,将会重复的那一行单独存下来,通过 printf()
的特性将
%c
是指代特殊字符。因为特殊字符转义是包含两个字符,所以为了方便,我们用 %c
表示特殊字符。
%s
是字符串重复的位置,我们通过 printf()
将重复的部分替换。
以上代码看上去码风很丑,不过这是为了使最后代码简洁。因为一旦加长代码,就会使
通过这种 “先将重复部分存下来不管,输出其他部分,最后在其他语句中将重复部分替换” 的思路,我们可以衍生出很多很多代码。比如这个:
把括号里的内容抄一遍,再带括号抄一遍,最后加个句号(把括号里的内容抄一遍,再带括号抄一遍,最后加个句号)。
自然语言
大家可以发现,按照这段话做一遍后,你会得到一个一模一样的段落!
还有很多 Quine 程序的实现。大家可以查阅资料。能输出自己的程序,就这样被我们创造出来了!是不是不敢相信?到此,我们大功告成!