Quine —— 能够自我繁殖的程序生命

· · 算法·理论

\\ \color{red}\texttt{\footnotesize{包含但不限于制作病毒,抄袭。}}

声明:本文原创,部分灵感参考于

禁止抄袭。

你是否有过一个念头:“我要写一个能输出自己的程序!”
目的呢,可能是想要挑战、娱乐、炫耀。
但是,经过七七四十九般尝试,你依然没有研究出来这种程序。
不过,看完这篇文章,你就会 Get 到以前让你不敢相信的代码! 那就让我们尝试写一写吧!

提示:我是 C++ 党,所以本文的所有代码都是用 C++ 编写的。不过,尽管你不会 C++,只要读懂了思路,稍加变通,我相信你也一定能成功!

Part 1 一次大胆的尝试

首先,凡是代码都有框架:\texttt{\tiny{注:这里省略了主函数以外的部分与主函数}}

cout << "...";

然后,我们要将代码里的 ... 替换成整个代码,注意特殊字符的转义:

cout << "cout << \"...\"";

emmm,又出现了一个 ...,按照规矩,我们应该把它也替换成整个代码。

cout << "cout << \"cout << \"cout << \"...\"\";\"";

emmm,还有一个 ...,所以继续替换……
等等,你有没有发现什么不对劲的地方?

Part 2 无法打破的 “造物论”

看着上方越来越长的代码,你不禁陷入深思。
照这么写,我的代码要写 INF 列啊!!!QWQ \texttt{\tiny{注:INF是无穷大的意思。}}
我们貌似发现了一个无法打破的理论,我们暂且称之为 “造物论”。该理论指出,任何一种物质,都只能由比其跟高级的物质造出。例如,汽车厂造出汽车,人类造出玩具。(我们的程序也可以由 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() 的特性将 s 的重复部分用 s 替代。

%c 是指代特殊字符。因为特殊字符转义是包含两个字符,所以为了方便,我们用 %c 表示特殊字符。

%s 是字符串重复的位置,我们通过 printf() 将重复的部分替换。

以上代码看上去码风很丑,不过这是为了使最后代码简洁。因为一旦加长代码,就会使 s 的长度增加。

通过这种 “先将重复部分存下来不管,输出其他部分,最后在其他语句中将重复部分替换” 的思路,我们可以衍生出很多很多代码。比如这个:

把括号里的内容抄一遍,再带括号抄一遍,最后加个句号(把括号里的内容抄一遍,再带括号抄一遍,最后加个句号)。

自然语言

大家可以发现,按照这段话做一遍后,你会得到一个一模一样的段落!

还有很多 Quine 程序的实现。大家可以查阅资料。能输出自己的程序,就这样被我们创造出来了!是不是不敢相信?到此,我们大功告成!

End