我已经看到了很多的基于C / C ++解决这个问题,我们必须写在执行时打印出它自己的源的程序。
一些解决方案 -
http://www.cprogramming.com/challenges/solutions/self_print.html
在许多语言奎因页的解决方案
有在网上更多的解决方案,从其他各不同。 我不知道我们该怎么办的方法来这样一个问题,谁解决它的人的头脑里发生的事情。 借给我一些见解这个问题......而在如Perl,PHP,红宝石等解释语言的解决方案可能是简单的......我想知道一个人如何去编译语言设计它...
除了cheating¹有编译和解释语言之间没有什么区别。
通用方法基内斯是很容易的。 首先,无论该程序的样子,在某些时候它有打印的东西:
print ...
然而,应该列印吗? 本身。 因此,它需要打印的“打印”命令:
print "print ..."
它应该下一个打印? 那么,在平均时间程序的增长,所以它需要打印字符串开始“打印”,太:
print "print \"print ...\""
现在程序又变得,如此反复多有打印:
print "print \"print \\\"...\\\"\""
等等。 随着每一次添加的代码有更多的代码来打印。 这种做法越来越行不通,但它揭示了一个有趣的现象:字符串“打印\””重复一遍又一遍这将是很好把重复的部分到一个变量:
a = "print \""
print a
然而,该方案只是改变了,所以我们需要调整:
a = "a = ...\nprint a"
print a
当我们现在尽量填写的“...”,我们遇到了同样的问题之前。 最终,我们想写的东西是这样的:
a = "a = " + (quoted contents of a) + "\nprint a"
print a
但是,这是不可能的,因为即使我们有这样一个函数quoted()
的报价,还是有我们定义问题a
在自身方面:
a = "a = " + quoted(a) + "\nprint a"
print a
因此,我们可以做的唯一事情就是把一个占位符成a
:
a = "a = @\nprint a"
print a
这就是整个招! 还有什么是现在很清楚。 只需使用的引用内容替换占位符a
:
a = "a = @\nprint a"
print a.replace("@", quoted(a))
既然我们已经改变了代码,我们需要调整的字符串:
a = "a = @\nprint a.replace(\"@\", quoted(a))"
print a.replace("@", quoted(a))
就是这样! 在所有语言的所有基内斯工作方式(除作弊的)。
那么,你应该确保你只替换占位符的第一次出现。 如果你使用第二个占位符,就可以避免需要引用的字符串。
但这些都是小问题,容易解决的问题。 如果事实,实现quoted()
和replace()
是其中的各种基内斯真正不同的唯一细节。
通过使程序读取惫它的源文件
有写作基内斯几个不同的策略。 最明显的一个是只写打开的代码,并打印出来的代码。 但更有趣的涉及语言功能,能够进行自我嵌入,像在许多语言%S型printf功能。 你必须弄清楚如何使之最终解析请求将被嵌入嵌入的东西。 我怀疑,像回文,大量的试验和错误的参与。
你也可以学习核心战争游戏是如何工作的。 这将会是一个很好的例子,我想。
通常的方法(当你不能欺骗*)是写一些东西,它的编码源字符串常量,然后打印出该常量两次:一次是作为一个字符串,并一度作为代码。 这在各地得到“我写一行代码每一次,我必须写另一个打印出来!” 问题。
“作弊”包括: - 使用一种解释语言,并简单地加载源进行打印 - 0字节长的文件,这是有效的在某些语言中,如C.
为了好玩,我想出了一个方案,这点我是很骄傲的约5分钟,直到我发现之前已经发现了。 不管怎么说,有一个轻微修改的游戏“规则”对数据的双重性和代码Lisp的好算的:不是打印出程序的源代码,这是一个S-表达式返回本身:
((lambda (x) (list x `',x)) '(lambda (x) (list x `',x)))
在维基百科上一个具有相同的概念,但略有不同的(更详细的)机制引用。 我喜欢我的,虽然比较好。
一个想法去想编码和如何给一些有双重含义,以便它可以在一对夫妇的形式来输出的东西。 还有,这种类型的问题自带的限制,使其更难,因为没有比程序输出本身以外的任何规则的cavaet,空的程序是一个解决方案。
你可以找到相当多的解决方案,这在这里: http://forums.thedailywtf.com/forums/p/5232/147528.aspx
如何真正阅读和打印您的源代码? 它一点都不难! 下面有一个在PHP中:
<?php
{
header("Content-Type: text/plain");
$f=fopen("5.php","r");
while(!feof($f))
{
echo fgetc($f);
}
fclose($f);
}
?>
在Python中,你可以这样写:
s='c=chr(39);print"s="+c+s+c+";"+s';c=chr(39);print"s="+c+s+c+";"+s
从这种自我印刷伪代码启发:
Print the following line twice, the second time with quotes.
"Print the following line twice, the second time with quotes."
我已经做了AS3例如,对于那些有兴趣在这
var program = "var program = @; function main(){trace(program.replace('@',
String.fromCharCode(34) + program + String.fromCharCode(34)))} main()";
function main(){
trace(program.replace('@', String.fromCharCode(34) + program + String.fromCharCode(34)))
}
main()