18

我遇到了这个术语 - Quine(也称为自我复制程序)。只是想了解更多。一个人如何写一个quine,它们是否在任何地方使用,或者它们只是一种娱乐练习?

我已经开始使用 Python,我可能会尝试用 Python 编写一个。有什么建议么?

4

10 回答 10

29

Quines 在实际意义上是无用的,但它们是一个很好的练习,可以帮助您更多地了解一门语言。

这是python中非常简洁的一个:

a='a=%r;print a%%a';print a%a
于 2009-07-10T21:59:52.863 回答
19

至少,quines 是产生自己的源代码作为输出的程序。它们是构建哥德尔不完备性证明的必要步骤。

这是否构成实际用途,我不予置评。

于 2009-07-10T20:51:15.157 回答
11

quine 是一种计算机程序,它生成自己的源代码副本作为其唯一输出。

我还没有看到一个实际用途,但我敢肯定在某个地方有一个。


Python 示例(在此处找到

print (lambda s:s+`s`+')')("print (lambda s:s+`s`+')')(")

C 示例(在此处找到

#include <stdio.h>
 
int main(int argc, char** argv)
{
/* This macro B will expand to its argument, followed by a printf
 command that prints the macro invocation as a literal string */
#define B(x) x; printf("  B(" #x ")\n");
 
/* This macro A will expand to a printf command that prints the
 macro invocation, followed by the macro argument itself. */
#define A(x) printf("  A(" #x ")\n"); x;
 
/* Now we call B on the text of the program
 up to this point. It will execute the command, and then cause
 itself to be printed. */
  B(printf("#include <stdio.h>\n\nint main(int argc, char** argv)\n{\n/*
    This macro B will expand to its argument, followed by a printf\n
    command that prints the macro invocation as a literal string
    */\n#define B(x) x; printf(\"  B(\" #x \")\\n\");\n\n/* This macro
    A will expand to a printf command that prints the\n
    macro invocation, followed by the macro argument itself. */\n#define A(x)
    printf(\"  A(\" #x \")\\n\"); x;\n\n/* Now we call B on the text
    of the program\n up to this point. It will execute the command,
    and then cause\n itself to be printed. */\n"))
  A(printf("/* Lastly, we call A on a command to print the remainder
    of the program;\n it will cause itself to be printed, and then
    execute the command. */\n}\n"))
/* Lastly, we call A on a command to print the remainder of the program;
 it will cause itself to be printed, and then execute the command. */
}
于 2009-07-10T20:41:31.697 回答
9

正如其他人解释的那样,quines 是复制自己的精确副本的程序。

关于应用程序,如果你认为 DNA 编码逻辑来解释自己并自我复制 - 答案很简单,没有 quines 的概念,我们就不会在这里,我们将永远无法创造人工(自我复制) 生活。

于 2009-11-19T17:08:58.790 回答
6

这是我最喜欢的 C 示例

char*p="char*p=%c%s%c;main(){printf(p,34,p,34);}";main(){printf(p,34,p,34);}

我从中学到了两件事:

  1. 不需要空格,但确实有助于提高可读性
  2. prinftf 功能真的很强大
于 2009-10-01T19:57:07.743 回答
4

我无法提供任何数据来说明写一两个 quine 扩展了我的思维或让我成为了一个更好的程序员。但这很有趣,至少在前几次。无论如何,你问如何写一个。我可以为您指出一些写得很好的参考资料:

Craig Kaplan 有一篇简洁的论文描述了如何实际生产 quines:

  • 搜索自记录代码
    • 本报告探讨了编写自记录程序的问题:该程序在运行时会产生自身作为输出。这个问题是从自引用的角度来审视的,自记录程序必须表现出的属性。该报告从无法正常工作的早期程序开始,到接近解决方案的连续复杂程序,再到工作的自我记录程序。然后它稍微退后一步,展示了一些程序如何看似作弊并且仍然符合自文档程序的定义,并建议对该定义进行改进。在每个步骤中,报告都说明了给定程序如何展示计算机编程和自我引用之间的微妙关系。

您可能还会发现 David Madore 的“Quines(自我复制程序)”很有趣。

最后,如果您想查看实现,请查看Quine 页面,您可以在其中找到各种语言和其他相关内容的 quines。

于 2009-07-11T00:27:44.147 回答
2

奎因是做什么用的?编程练习和病毒。

病毒需要以某种方式复制——一种方法是让它成为一种病毒。假设一个假设的防病毒程序会标记任何将自己的二进制文件读入内存的进程(以将其传递给目标受害者);解决这个问题的方法是让它自己输出。

请记住,机器代码中的 quine 不需要编译。

于 2009-07-11T02:45:27.550 回答
1

这是 Python 中的一个(它很难看;我只是写它来尝试一下)。那时甚至不知道这被称为quine。

def e(s): print s[:42]+s[42:].replace('#','"'); print 'e("""'+s+'""")'
e("""def e(s): print s[:42]+s[42:].replace('#','"'); print 'e(###'+s+'###)'""")

哦,回答你的另一个问题:Quines 完全没用。

于 2009-07-10T20:42:09.013 回答
1

1979 年,我用 Fortran 编写了我的第一个 Quine。前几天我对 PHP 中的 Quines 有一个随机的想法,感觉想发布与 OP 相同的 Q,但作为一个好孩子,我首先检查了 Q&A D/B。无论如何,这里是我的 PHP(cli) quine。我会对任何较短的变体感兴趣。:-)

<?php $x='<?php $x=0;echo strtr( $x, array(chr(39).$x.chr(39)));';echo strtr( $x, array(chr(39).$x.chr(39)));

109 字节,但最后一个 CR 被切断。这还不包括“作弊”:

<?php readfile( __FILE__);

这个QuineProgram wiki 引用了一个更短的:

<?php printf($a='<?php printf($a=%c%s%c,39,$a,39);',39,$a,39);
于 2012-06-20T21:45:10.347 回答
0

这是 C++ 中一个有趣的 quine:http: //npcomplete.weebly.com/1/post/2010/02/self-reproduce-c-program-quine.html

奎因是为了好玩。据我所知,它们没有实际用途。

于 2010-03-13T00:10:09.167 回答