Programming languages 如何编写自复制代码(在exec上打印源代码)?
我见过很多基于C/C++的解决方案,我们必须编写一个程序,在执行时打印自己的源代码 一些解决方案-- 网络上有许多不同的解决方案。我想知道我们如何处理这样一个问题,解决这个问题的人的内心是什么。请给我一些关于这个问题的见解。。。虽然像perl、php、ruby等解释语言的解决方案可能很简单。。。我想知道如何用编译语言设计它…在ruby中:Programming languages 如何编写自复制代码(在exec上打印源代码)?,programming-languages,quine,Programming Languages,Quine,我见过很多基于C/C++的解决方案,我们必须编写一个程序,在执行时打印自己的源代码 一些解决方案-- 网络上有许多不同的解决方案。我想知道我们如何处理这样一个问题,解决这个问题的人的内心是什么。请给我一些关于这个问题的见解。。。虽然像perl、php、ruby等解释语言的解决方案可能很简单。。。我想知道如何用编译语言设计它…在ruby中: puts File.read(uu_u文件uu)写quines有两种不同的策略。最明显的一个方法是编写代码,打开代码并打印出来。但更有趣的是涉及允许自嵌入
puts File.read(uu_u文件uu)写quines有两种不同的策略。最明显的一个方法是编写代码,打开代码并打印出来。但更有趣的是涉及允许自嵌入的语言功能,如许多语言中的%s风格printf功能。您必须弄清楚如何嵌入某些内容,以便最终解决要嵌入的请求。我怀疑,就像回文一样,需要大量的尝试和错误。通常的方法(当你不能作弊时*)是写一些东西,将其源代码编码为字符串常量,然后打印出该常量两次:一次作为字符串文本,一次作为代码。这就解决了“每次我写一行代码时,我必须再写一行才能打印出来”的问题 “作弊”包括: -使用解释语言,只需加载源代码并打印即可
-0字节长的文件,在某些语言中是有效的,例如C。一个想法是考虑编码,以及如何赋予某些内容双重含义,以便可以使用它以多种形式输出某些内容。还有一点值得注意的是,这种类型的问题带有一些限制,使问题变得更加困难,因为除了程序输出本身之外,没有任何规则,空程序就是一种解决方案。除了作弊之外,编译语言和解释语言之间没有区别 奎因的通用方法相当简单。首先,不管程序看起来像什么,在某个时候它必须打印一些东西: print ... 因此,我们唯一能做的就是将占位符放入
a
:
a = "a = @\nprint a"
print a
a = "a = @\nprint a"
print a.replace("@", quoted(a))
既然我们改变了密码,
我们需要调整字符串:
a = "a = @\nprint a.replace(\"@\", quoted(a))"
print a.replace("@", quoted(a))
a=“a=@\n打印a.replace(\“@\”,引号(a))”
打印a.替换(“@”,引用(a))
就这样!
所有语言中的所有奎因都是这样工作的
(作弊者除外)
嗯,你应该确保你只更换
占位符的第一次出现。
如果你使用第二名持有者,
您可以避免引用字符串
但这些都是小问题
而且容易解决。
如果是事实,quoted()
和replace()
是不同奎因真正不同的唯一细节
通过让程序读取其源文件以获得乐趣,我在Scheme中找到了一个,我为此感到非常自豪,大约5分钟,直到我发现了以前的发现。无论如何,游戏的“规则”有一点修改,以更好地计算Lisp中数据和代码的双重性:它不是打印程序的源代码,而是返回自身的s表达式:
((lambda (x) (list x `',x)) '(lambda (x) (list x `',x)))
具有相同的概念,但引用机制稍有不同(更详细)。不过我更喜欢我的。阅读并打印源代码怎么样?一点也不难!!在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()
在bash中,这真的很容易 触摸试验;chmod oug+x测试/试验
空文件,空输出实际上,几乎所有语言都有可以将源代码引入二进制文件的编译器(选项)。但是,免费阅读编译器/解释器提供给你的信息根本不是这个问题的重点。quine在接受输入或从文件中读取时无效实际上,你能拥有的最小C文件是:main;dsm$echo main\;>test.c dsm$gcc-o test test.c test.c:1:警告:数据定义没有类型或存储类dsm$。/测试分段错误dsm$dsm$许多c编译器将0字节文件编译成一个不输出任何内容并终止的可执行文件。我一直计算这些值,因为输入REPL,实际上,您确实看到该程序再次出现。这不算,因为在REPL中,您可以只编写一个字符串,例如ruby中的
“a”
,它将返回自身。但是,如何避免在replace(\“@\”,引号(a))部分中替换@?据我所知,替换只应在@的第一次出现时进行,即@\n打印。我说得对吗?即替换应仅替换第一个出现的符号?请共享更多详细信息。OP要求使用编译语言提供解决方案,我不会说bash脚本是以任何方式编译的
a = "a = @\nprint a"
print a.replace("@", quoted(a))
a = "a = @\nprint a.replace(\"@\", quoted(a))"
print a.replace("@", quoted(a))
((lambda (x) (list x `',x)) '(lambda (x) (list x `',x)))
<?php
{
header("Content-Type: text/plain");
$f=fopen("5.php","r");
while(!feof($f))
{
echo fgetc($f);
}
fclose($f);
}
?>
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."
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()