Programming languages 如何编写自复制代码(在exec上打印源代码)?

Programming languages 如何编写自复制代码(在exec上打印源代码)?,programming-languages,quine,Programming Languages,Quine,我见过很多基于C/C++的解决方案,我们必须编写一个程序,在执行时打印自己的源代码 一些解决方案-- 网络上有许多不同的解决方案。我想知道我们如何处理这样一个问题,解决这个问题的人的内心是什么。请给我一些关于这个问题的见解。。。虽然像perl、php、ruby等解释语言的解决方案可能很简单。。。我想知道如何用编译语言设计它…在ruby中: puts File.read(uu_u文件uu)写quines有两种不同的策略。最明显的一个方法是编写代码,打开代码并打印出来。但更有趣的是涉及允许自嵌入

我见过很多基于C/C++的解决方案,我们必须编写一个程序,在执行时打印自己的源代码

一些解决方案--

网络上有许多不同的解决方案。我想知道我们如何处理这样一个问题,解决这个问题的人的内心是什么。请给我一些关于这个问题的见解。。。虽然像perl、php、ruby等解释语言的解决方案可能很简单。。。我想知道如何用编译语言设计它…

在ruby中:


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()