如何编写自我复制代码(在exec上打印源代码)? [英] How to write a self reproducing code (prints the source on exec)?

查看:176
本文介绍了如何编写自我复制代码(在exec上打印源代码)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看到了很多基于C/C ++的解决方案,我们必须编写一个程序,该程序在执行时会打印自己的源代码.

一些解决方案-

http://www.cprogramming.com/challenges/solutions/self_print.html

多种语言的Quine Page解决方案

网络上还有更多解决方案,每个解决方案互不相同.我想知道我们如何解决这个问题,解决这个问题的人的内心深处.向我提供有关此问题的一些见解...虽然解释语言(如perl,php,ruby等)的解决方案可能很简单...我想知道如何用编译语言进行设计...

解决方案

除了作弊¹,编译语言和解释语言之间没有区别.

用普通方法制作藜麦很容易.首先,无论程序是什么样,它都必须打印一些内容:

print ...

但是,它应该打印什么?本身.因此它需要打印"print"命令:

print "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()的实现 唯一的细节是各个quines确实有所不同.


¹通过使程序读取其源文件

I have seen a lot of C/C++ based solutions to this problem where we have to write a program that upon execution prints its own source.

some solutions --

http://www.cprogramming.com/challenges/solutions/self_print.html

Quine Page solution in many languages

There are many more solutions on the net, each different from the other. I wonder how do we approach to such a problem, what goes inside the mind of the one who solves it. Lend me some insights into this problem... While solutions in interpreted languages like perl, php, ruby, etc might be easy... i would like to know how does one go about designing it in compiled languages...

解决方案

Aside from cheating¹ there is no difference between compiled and interpreted languages.

The generic approach to quines is quite easy. First, whatever the program looks like, at some point it has to print something:

print ...

However, what should it print? Itself. So it needs to print the "print" command:

print "print ..."

What should it print next? Well, in the mean time the program grew, so it needs to print the string starting with "print", too:

print "print \"print ...\""

Now the program grew again, so there's again more to print:

print "print \"print \\\"...\\\"\""

And so on. With every added code there's more code to print. This approach is getting nowhere, but it reveals an interesting pattern: The string "print \"" is repeated over and over again. It would be nice to put the repeating part into a variable:

a = "print \""
print a

However, the program just changed, so we need to adjust a:

a = "a = ...\nprint a"
print a

When we now try to fill in the "...", we run into the same problems as before. Ultimately, we want to write something like this:

a = "a = " + (quoted contents of a) + "\nprint a"
print a

But that is not possible, because even if we had such a function quoted() for quoting, there's still the problem that we define a in terms of itself:

a = "a = " + quoted(a) + "\nprint a"
print a

So the only thing we can do is putting a place holder into a:

a = "a = @\nprint a"
print a

And that's the whole trick! Anything else is now clear. Simply replace the place holder with the quoted contents of a:

a = "a = @\nprint a"
print a.replace("@", quoted(a))

Since we have changed the code, we need to adjust the string:

a = "a = @\nprint a.replace(\"@\", quoted(a))"
print a.replace("@", quoted(a))

And that's it! All quines in all languages work that way (except the cheating ones).

Well, you should ensure that you replace only the first occurence of the place holder. And if you use a second place holder, you can avoid needing to quote the string.

But those are minor issues and easy to solve. If fact, the realization of quoted() and replace() are the only details in which the various quines really differ.


¹ by making the program read its source file

这篇关于如何编写自我复制代码(在exec上打印源代码)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆