Quine—— 输出自身的程序
如果一段程序的代码运行之后,产生的输出和其自身的源码完全相同,那么这段程序就被称为 Quine,以哲学家 Willard van Orman Quine(1908-2000)而命名。
Quine 在任何图灵完备,且能输出任意字符串的语言中都是可行的。在可计算性理论(computability theory)中,图灵等价指的是:对于两个计算机 A 和 B,如果 A 可以模拟 B,B 可以模拟 A,就称他们是图灵等价的。根据「丘奇 - 图灵」理论,图灵机是表达能力最强大的计算系统,对现实世界中的任何计算机,都可以用图灵机来模拟它。而如果一个编程语言可以完全模拟图灵机,那么它就是图灵完备的。
大部分编程语言都是图灵完备的,在这些语言中,构造 Quine 的思路也是类似的。Quine 中往往需要包含数据和程序两部分。数据是程序的表示(例如将程序中的特殊字符编码,存储在一个字符串中),而程序负责解析数据并将其输出。此外,利用一些语言的语法特性也可以构造出比较简单的 Quine。
Bash
1 | z=\' a='z=\\$z a=$z$a$z\; eval echo \$a'; eval echo $a |
JavaScript
1 | !function $(){console.log('!'+$+'()')}() |
Python 3
1 | r='r=%r\nprint(r%%r)' |
C
1 | char*s="char*s=%c%s%c;main(){printf(s,34,s,34);}";main(){printf(s,34,s,34);} |
上面这个有些赖皮,直接读取并输出了源代码。有些 Quine 规则会不允许这样做。
PHP
1 | echo file_get_contents(__FILE__); |
这个同样是赖皮做法,笔者后来又仿造 C 语言的 Quine 的构思了一个
1 | $s = '<?php $s = %c%s%c; printf($s, 39, $s, 39); ?>'; printf($s, 39, $s, 39); |
Rust
1 | fn main(){print!("{},{0:?})}}","fn main(){print!(\"{},{0:?})}}\"")} |
Perl
1 | $_=q{print"\$_=q{$_};eval"};eval |
Pascal
1 | CONST T=';BEGIN WRITE(#67#79#78#83#84#32#84#61#39,T,#39,T)END.';BEGIN WRITE(#67#79#78#83#84#32#84#61#39,T,#39,T)END. |
Brainfuck
1 | >+>+++>>+>++>+>+++>>+>++>>>+>+>+>++>+>>>>+++>+>>++>+>+++>>++>++>>+>>+>++>++>+>>>>+++>+>>>>++>++>>>>+>>++>+>+++>>>++>>++++++>>+>>++>+>>>>+++>>+++++>>+>+++>>>++>>++>>+>>++>+>+++>>>++>>+++++++++++++>>+>>++>+>+++>+>+++>>>++>>++++>>+>>++>+>>>>+++>>+++++>>>>++>>>>+>+>++>>+++>+>>>>+++>+>>>>+++>+>>>>+++>>++>++>+>+++>+>++>++>>>>>>++>+>+++>>>>>+++>>>++>+>+++>+>+>++>>>>>>++>>>+>>>++>+>>>>+++>+>>>+>>++>+>++++++++++++++++++>>>>+>+>>>+>>++>+>+++>>>++>>++++++++>>+>>++>+>>>>+++>>++++++>>>+>++>>+++>+>+>++>+>+++>>>>>+++>>>+>+>>++>+>+++>>>++>>++++++++>>+>>++>+>>>>+++>>++++>>+>+++>>>>>>++>+>+++>>+>++>>>>+>+>++>+>>>>+++>>+++>>>+[[->>+<<]<+]+++++[->+++++++++<]>.[+]>>[<<+++++++[->+++++++++<]>-.------------------->-[-<.<+>>]<[+]<+>>>]<<<[-[-[-[>>+<++++++[->+++++<]]>++++++++++++++<]>+++<]++++++[->+++++++<]>+<<<-[->>>++<<<]>[->>.<<]<<] |
Lisp(mit-scheme)
1 | ((lambda (x) (list x (list (quote quote) x))) (quote (lambda (x) (list x (list (quote quote) x))))) |
参考文章:
能不能写出一个代码,使代码的运行结果是输出这段代码本身? - 知乎
自生程式
Quines (self-replicating programs)
拓展阅读:
The Quine Page
是否无法写一段代码将这段代码自己打印出来? - 知乎
编程领域都有哪些牛逼闪闪的「禁术」? - 知乎
更多神奇的 Quine 代码:
quine-relay
quine-central
quinesnake
quine.bf