最长的周期重复


10

众所周知,quine是一个输出自己的源代码的程序。但是,也可以编写一个输出另一个不同程序的程序,该程序再次输出第一个程序。例如,Python 2程序

x = '''x = {}
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3'''
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3

运行时将输出以下文本:

print """x = '''x = {}
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3'''
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3"""

当作为Python程序运行时,这将再次输出原始代码。这被称为迭代奎因。因为您必须运行两次才能取回原始代码,所以我们说它的周期为2。但是,当然可以有更高的期限。

您面临的挑战是用您选择的语言编写一个尽可能长的迭代quin,以100字节或更小字节为单位。(请注意,我上面的示例不符合此规范,因为它是119个字节,包括结尾的换行符。)

请注意以下规则和说明:

  • 通常采用奎因规则,即您的程序不能使用允许其直接访问其自身源代码的语言功能。
  • 迭代后的输出最终必须精确地循环回到您的原始代码,并且您必须提供演示或证明。
  • 您还必须说明循环为何如此长。这不必一定要经过数学证明,但应该可以说服熟悉您的语言的人。(这条规则在这里是因为我希望某些答案涉及非常大的数字。)
  • 只要提供“至少1,000,000次迭代”之类的信息,而不是给出确切的数字,就可以了,只要您可以证明它至少那么长即可。在这种情况下,您的分数将是1,000,000。否则,您的分数就是您的寿命。
  • 100字节的限制仅适用于您的初始程序-它输出的程序可能会更长,尽管它们最终最终必须回落到100字节才能输出原始代码。
  • 您可以假定您的计算机具有无限的RAM和无限的运行时间,但是如果您的语言没有无限的精度数据类型(例如整数),则不能假定它们。您可以假设解析器可以处理的输入长度没有限制。
  • 最高分获胜。

请注意:存在一个称为“ 戒烟”的挑战启动Quining,这也涉及迭代quines。但是,除了基于相同的概念外,这些挑战是完全不同的类型。另一个是直线打高尔夫,而这个(故意!)确实是一个因变相而忙碌的海狸问题。能够很好地回答这个问题所需的技术可能与回答另一个问题所需的技术完全不同,而这在设计上是非常不同的。


1
@LeakyNun我不知道是你还是一个mod删除了你的答案,但是也许如果我解释出了问题所在,你将会理解为什么这不是重复的。这个问题指定了源长度的100个字节限制,因此使用该方法实际上无法“达到所需的高度”。这就是这个问题的全部重点。要回答这个问题,您所要做的就是发布适合100个字符的最长版本,并说出其期限。您发布的内容将是一次不错的尝试,但不太可能成为赢家。
纳撒尼尔(Nathaniel)

1
@Dave的挑战恰好是在少量字节中指定大量,是的。这就是设计它的整个原理。问题是,您可以用您的语言在100个字节中指定的最高数字3 ^^^ 3,还是更大的数字?这就是挑战所在。这是它的核心。这就是我希望人们看到的。基于与没有这种结构的挑战的表面相似,将其关闭是非常超级的。
纳撒尼尔(Nathaniel)

1
@Dave(第二条评论),但是如果您很聪明,则完全不需要受机器精度的限制。我希望竞争性答案的周期比2 ^(2 ^ 64)长得多。
纳撒尼尔(Nathaniel)

3
因此,您是否希望将其作为codegolf.stackexchange.com/q/18028/194的副本关闭?
彼得·泰勒

1
@PeterTaylor是一个更接近的主题,但这仍然是一个非常不同的挑战-打印数字与执行大量操作完全不同。我当然希望它根本不关闭。
纳撒尼尔(Nathaniel)2013年

Answers:


10

PHP,时期2,100,000,000

谁会想到这在PHP中是可能的?:-)

这实际上是我的第一个quine,它的长度为99个字节:

<?$i=1;$i*=21e8>$i;printf($a='<?$i=%d;$i*=21e8>$i;printf($a=%c%s%c,++$i,39,$a,39);',++$i,39,$a,39);

尽管PHP支持比2 * 10^8通过切换integer到更大的数字double,但增量不再起作用(导致无限循环),并且我还没有找到适合100字节的另一种解决方案。然而。

证明相当简单,因为它只是在每次迭代中累加,直到达到重置点21亿为止。

学分戴夫,谁张贴在评论和伪代码的方法鲍勃Twells,从他们那里我复制的代码,最小的PHP奎因。

测试程序(sloooooow):

<?php
$o = file_get_contents('quine.php');
for ($i = 0; $i < 22e8; $i++) {
    if ($i%2==0) exec('php q > p'); else exec('php p > q');
    $a = file_get_contents(($i%2==0) ? 'p' : 'q');
    echo "\r" . str_pad($i,6,' ') . ":\t$a";
    if ($a == $o) {
        die;
    }
}

好吧,至少我是第一个回答。


1
旁注:大约为10 ^ 9.322219295。
LegionMammal978'9

8

Mathematica,期间E8.5678#3 E2.1923# 4〜E6.2695#3#2

Print[ToString[#0, InputForm], "[", #1 - 1 /. 0 -> "Nest[#!,9,9^9^99!]", "]"] & [Nest[#!,9,9^9^99!]]

请注意,分数以Hyper-E表示法描述。迭代将最终结果替换为-1,-2,-3,...,3、2、1并返回到Nest[#!,9,9^9^99!]的十进制扩展。Nest[#!,9,9^9^99!]Nest[#!,9,9^9^99!]Nest[#!,9,9^9^99!]Nest[#!,9,9^9^99!]


阶乘成长不会更快吗?
Maltysen '16

1
我不了解Mathematica,但这不是违反规则的规则吗?请阅读它本身的源代码?ToString[#0, InputForm]
daniero

所以,只有9个!!!不起作用?idk cuz我现在没有我的mathematica rpi。
Maltysen '16

@Maltysen计算9的双阶乘的双阶乘,或(9 !!)!! ≈2.116870635·10¹²⁰²
LegionMammal978

@daniero我的意思是,这个想法类似于标准的CJam {"_~"}_~,所以我想它应该是有效的……
LegionMammal978 '09

5

R,期望为2 ^ 19936-0.5的随机周期

f=function(){
    options(scipen=50)
    body(f)[[4]]<<-sum(runif(623))
    0
    cat("f=")
    print(f)
}

R的默认随机数生成器的周期为2 ^ 19937-1,并且在623个连续维上均等分布。因此,在其周期的某个地方(但只有一次)将是一个623长的零向量。当我们到达那里(并与序列的开始对齐)时,接下来的623个随机U [0,1]数字的总和将为零,然后返回到原始程序。

请注意,在返回零之前,程序很有可能会多次通过相同的非零状态。例如,总和311.5最有可能发生,并且有很多方式可以发生,但是RNG允许0的周期比311.5的周期更长。


不确定要为该条目分配多少分:P
JDL

1
按照规则:“最好说“至少1,000,000次迭代”,而不是给出确切的数字。”所以我认为这是“至少1次迭代”,因为如果第一次尝试我们真的很幸运...;)
YetiCGN

与许多标准漏洞(例如“我可能会生成一些随机输入,答案就在这里”)不同,这确实证明了精确答案必定会发生,并且给出了很好的估计。真好!
安德烈KOSTYRKA

1
一旦程序返回到其基本状态一次,则它将具有恰好为2 ^ 19937-1的非随机周期。
JDL

它的输出与实际程序不匹配(缺少一些空格)。此外,在程序调用之间不会保留状态,因此该期间将不是确切的数字,也不是一致的
Jo King

1

JavaScript,期间9,007,199,254,700,000

不会赢,但是使用JavaScript应对这一挑战很有趣:

a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)

遵循以下周期:

a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254700000-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254699999-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254699998-1||90071992547e5)
// etc...
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),3-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),2-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254700000-1||90071992547e5)
// and so on

注意:您可以将其缩短18个字节,而仅删除分数的〜0.08%,如下所示:

a="a=%s;console.log(a,uneval(a),%.0f-1||9e15)";console.log(a,uneval(a),1-1||9e15)

1

C,期间2,100,000,000

unsigned long long i;main(a){i=1;i*=21e8>i;printf(a="ungisned long long i;main(a){i=%d;i*=21e8>i;printf(a=%c%s%2$c,++i,34,a);}",++i,34,a);}

基于PHP答案(显然)。有时间的时候会更新说明。


1

C(gcc),66个字节,周期2 ^ 64

f(s){printf(s="f(s){printf(s=%c%s%1$c,34,s,%lu+1L);}",34,s,0+1L);}

在线尝试!

2 ^ 64个数字可用unsigned long整数。因此,周期为2 ^ 64。


1

Python 2

期: 9((99↑↑(9((99↑↑(9((99↑↑(9↑↑51))9)1))9)1))9)+1

感谢@Bubbler延长了从 99(99↑↑12)+1 到现在

b=0;s="print'b=%d;s=%r;exec s'%(-~b%eval('9**9'*eval('9**9'*eval('9**9'*9**9**9**9**9))),s)";exec s

在线尝试!

在代码中,b=0b=1then 的更改b=2,依此类推,直到到达,b=decimal expansion of the period然后重置为b=0


1
9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9比更高9**9**99**99**99**99**99**99**99**99**99**99**99**99。也就是说,您可以eval('9**9'*eval('9**9'*eval('9**9'*9**9**9**9**9)))为更多的数字做类似的事情。
鼓泡

骨oid是什么意思?
SS安妮

@SSAnne它是写在Knuth的向上箭头符号
穆昆丹

1
@Mukundan我想您可能指的是时期,但我不确定。我知道什么是四方。
SS安妮

@SSAnne对不起,这是一个错字,感谢您指出
Mukundan

0

Gol> <>,70个字节,周期32588319662129709705760020617571905647680487948828870818800327491986095953477010107951243339634806280305573964022539575879085231587686846939060379372963971590813619650590816523612713615428796947583901754481192603680808959620908187207203520

其他明智的称为真正的大(3.25E270)

":1=l8:*6+=S&Q~:'~'=Q~~'H#'||lPffXfX=?1:1=Q$~$~|:1)lPffXfX(Q?:|r2ssH##

这实际上是我在500字节迭代器上添加的答案的更改版本

":1=l8:*6+=S&Q~:'~'=Q~~'H#'||//if last is equal to 1 and length is 71, delete the delete char, if the last char is '~', delete and push 'H#', which will later return to 'H##', completing the cycle!
lPffXfX=?1:1=Q$~$~|          //if length is equal to 15^15^15, then start delete process(append ascii one)
:1)lPffXfX(Q?:|              //if the last character is not 1 (the delete checker), and length is less than 15^15^15, duplicate the last value and append
r2ssH##                      //push the " to the front and output the whole thing

希望我的分数正确,并且没有错误。理论上,没有实际方法可以实际计算该值。但是,伙计,这是一个巨大的数字!

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.