构造奎因(自我复制功能)

发布于 2024-11-17 04:11:48 字数 1155 浏览 4 评论 0原文

有没有人构建过 quine(“生成自己源文本的副本作为其完整输出的程序”:http://www.nyx.net/~gthompso/quine.htm)在 R 中? ([quine] 标签在 Python、Java 中提取了大量示例,...但显然在 R 中没有。)

f <- function() { body() }

很接近:

> f()
{
    body()
}

但缺少函数名称。

最短的可能性怎么样?最困惑?

编辑:从下面的各种答案来看,似乎有多种方法可以定义自引用及其必须发生的环境:

  • 在R环境中:函数-> ;操作系统/shell 环境中的 函数 (@bill_080)
  • :program -> 程序 [或多或少等同于program -> 文本]: ( @kohske)
  • 其他:功能-> 文本(@JoshUlrich、@James,问题如上定义)

注释:

  • @Spacedman 指出的 R-help 线程(似乎强调混淆而不是简洁)表明identical(quine,quine()) 是一个很好的测试用例,尽管它很棘手,因为环境会一直进行:identical(quine,quine(),ignore.environment=TRUE) 可能会更容易。
  • 最近(2015 年 10 月)博客文章提供了另一个答案......

Has anyone constructed a quine ("A program that generates a copy of its own source text as its complete output": http://www.nyx.net/~gthompso/quine.htm) in R? (The [quine] tag pulls up lots of examples in Python, Java, ... but apparently none in R.)

f <- function() { body() }

comes close:

> f()
{
    body()
}

but lacks the name of the function.

How about the shortest possibility? Most obfuscated?

edit: from the variety of answers below, it seems that there are a variety of ways to define self-referentiality and the environment in which it must occur:

  • within the R environment: function -> function (@bill_080)
  • within the OS/shell environment: program -> program [more or less equivalent to program -> text]: (@kohske)
  • other: function -> text (@JoshUlrich, @James, problem as defined above)

Notes:

  • The thread from R-help pointed out by @Spacedman (which seems to emphasize obfuscation over brevity) suggests that identical(quine,quine()) is a good test case, although it's tricky because environments get carried along: identical(quine,quine(),ignore.environment=TRUE) might be easier.
  • A recent (Oct 2015) blog post provides another answer ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

-小熊_ 2024-11-24 04:11:48

这是我能想到的最短的:

> "f" <- function() call("<-", "f", f)
> f()
"f" <- function () 
call("<-", "f", f)

This is the shortest I can come up with:

> "f" <- function() call("<-", "f", f)
> f()
"f" <- function () 
call("<-", "f", f)
不必了 2024-11-24 04:11:48

这是一个真正的奎因,一个程序(不是函数),它生成自己的源文本的副本作为其完整的输出。

在控制台上,

# y1.R is a quine program
$ cat y1.R
(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})("(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})")

# execute y1.R and show output
$ /usr/bin/R --vanilla --slave < y1.R
(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})("(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})")

# save the output of the execution of y1
$ /usr/bin/R --vanilla --slave < y1.R > y2.R

# compare input and output -- exactly same.
$ diff y1.R y2.R

这可能不是最短的。

更新:

和稍短的版本:

(function(x){cat(x,'(',d<-intToUtf8(0x0022),x,d,')',sep='')})("(function(x){cat(x,'(',d<-intToUtf8(0x0022),x,d,')',sep='')})")

Here is a real Quine, a program (not a function) that generates a copy of its own source text as its complete output.

On console,

# y1.R is a quine program
$ cat y1.R
(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})("(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})")

# execute y1.R and show output
$ /usr/bin/R --vanilla --slave < y1.R
(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})("(function(x){cat(x);cat('(');cat(intToUtf8(0x0022));cat(x);cat(intToUtf8(0x0022));cat(')')})")

# save the output of the execution of y1
$ /usr/bin/R --vanilla --slave < y1.R > y2.R

# compare input and output -- exactly same.
$ diff y1.R y2.R

probably this is not the shortest one.

UPDATED:

and slightly shorter version:

(function(x){cat(x,'(',d<-intToUtf8(0x0022),x,d,')',sep='')})("(function(x){cat(x,'(',d<-intToUtf8(0x0022),x,d,')',sep='')})")
冧九 2024-11-24 04:11:48

body 的作用为灵感,call 可用于重现调用命令:

f <- function () 
{
    call("<-", as.name(as.character(sys.calls()[[1]])), sys.function(sys.parent()))
}

输出:

> f()
f <- function () 
{
    call("<-", as.name(as.character(sys.calls()[[1]])), sys.function(sys.parent()))
}

Using what body does as inspiration, call can be used to reproduce the calling command:

f <- function () 
{
    call("<-", as.name(as.character(sys.calls()[[1]])), sys.function(sys.parent()))
}

Which outputs:

> f()
f <- function () 
{
    call("<-", as.name(as.character(sys.calls()[[1]])), sys.function(sys.parent()))
}
彩虹直至黑白 2024-11-24 04:11:48

如果你想要一个返回函数的函数......也许是这个?

junk <- function(...) {
  function(...) {
    structure(junk(...))
  }
}

输出是:

> junk()

function(...) {
    structure(junk(...))
  }
<environment: 01ef8e50>


> boo <- junk(999)
> boo

function(...) {
    structure(junk(...))
  }
<environment: 020e1048>


>dput(boo)

function (...) 
{
    structure(junk(...))
}

If you want a function that returns a function.....maybe this?

junk <- function(...) {
  function(...) {
    structure(junk(...))
  }
}

The output is:

> junk()

function(...) {
    structure(junk(...))
  }
<environment: 01ef8e50>


> boo <- junk(999)
> boo

function(...) {
    structure(junk(...))
  }
<environment: 020e1048>


>dput(boo)

function (...) 
{
    structure(junk(...))
}
南汐寒笙箫 2024-11-24 04:11:48

虽然我不确定从 quine 的角度来看这是否“重要”(我在尝试验证是否有效时偶然发现了这个问题),但脚本

function(){}

将输出 function(){}。这与 Joshua Ulrich 的答案的原理相同,只是精简到了要点。

While I'm not sure if this "counts" from a quine perspective (I stumbled across this question while trying to verify if it does), the script

function(){}

will output function(){}. This works on the same principle as Joshua Ulrich's answer, just pared down to the essentials.

留一抹残留的笑 2024-11-24 04:11:48

@Spacedman 的回答,来自 r-help 邮件列表2003(线程中还有更多示例):

好吧,我设法将 quine 网页上的 javascript quine 修改为
创建这个怪物 - 只需将其全部粘贴在文件中的一行上 - 我已经
为了清晰起见,将其拆分在这里:

a=1:10;a[1]='a=1:10;';a[2]='[';a[3]=']';a[4]='\'';a[5]='\\';a[6]='=';a[7]='a';a[8]=';';a[9]='';

a[10]='for(i in 1:10)cat(ifelse(i==1,a[1],a[9])

,a[7],a[2],i,a[3],a[6],a[4],ifelse(i==4||i==5,a[5],a[9]),

a[i],a[4],a[8],ifelse(i==10,a[10],a[9]),sep=a[9])';for(i in 1:10)

cat(ifelse(i==1,a[1],a[9]),a[7],a[2],i,a[3],a[6],a[4],

ifelse(i==4||i==5,a[5],a[9]),a[i],a[4],a[8],ifelse(i==10,a[10],a[9]),sep=a[9])

这通过了 quine 脚本测试:

$ R --slave < q2.R >q2o.R
$ diff q2.R q2o.R
  <nothing!>
$

我确信如果我理解它,我可以做得更好...

原始 javascript 版本作者:Geoffrey A Swift(blimey at toke.com)
来自:http://www.nyx.net/~gthompso/quine.htm

An answer from @Spacedman, from the r-help mailing list in 2003 (there are more examples in the thread):

Well I managed to modify a javascript quine on the quine web page to
create this monster - simply stick it all on one line in a file - I've
split it here for an attempt at clarity:

a=1:10;a[1]='a=1:10;';a[2]='[';a[3]=']';a[4]='\'';a[5]='\\';a[6]='=';a[7]='a';a[8]=';';a[9]='';

a[10]='for(i in 1:10)cat(ifelse(i==1,a[1],a[9])

,a[7],a[2],i,a[3],a[6],a[4],ifelse(i==4||i==5,a[5],a[9]),

a[i],a[4],a[8],ifelse(i==10,a[10],a[9]),sep=a[9])';for(i in 1:10)

cat(ifelse(i==1,a[1],a[9]),a[7],a[2],i,a[3],a[6],a[4],

ifelse(i==4||i==5,a[5],a[9]),a[i],a[4],a[8],ifelse(i==10,a[10],a[9]),sep=a[9])

This passes the quine script test:

$ R --slave < q2.R >q2o.R
$ diff q2.R q2o.R
  <nothing!>
$

I'm sure if I understood it I could make it better...

Original javascript version by: Geoffrey A Swift (blimey at toke.com)
From: http://www.nyx.net/~gthompso/quine.htm

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文