奎因是一个在运行时输出其源的程序。
在这个挑战中,你应该做一个斐波纳契-奎因,奎因的变体。
Fibonacci是一个程序,它通过以下规则输出源的修改:
初始源应该是...2...。换句话说,源应该包含2。(为什么是2?如果是1,没人会知道它是第一个还是第二个,甚至是程序本身)
运行时,您应该输出源,但只有特定的数字(在这个阶段,2)更改为fibonacci序列的下一个编号。例如,...3...。输出和输出的输出也是一样的,等等,你可以支持最多2^32-1的整数。对于超过该限制的整数,下一个输出取决于您的选择。
OP的笔记,我真的很想看到一个创造性的解决方案。我想不出解决这个问题的单一方案,因为挑战的两个重要方面斐波纳契和奎因都不容易。那我就等你了!
发布于 2017-05-08 11:11:40
ToString[#0 /. v:2 :> RuleCondition[Round[GoldenRatio v]]] & 请注意,有一个尾随空间。这是一个函数quine,即上面的代码计算为一个未命名的函数,如果被调用,该函数将代码本身作为字符串返回(将2更改为下一个Fibonacci数)。
让人吃惊的是,这件事很难开始工作。基本思想是(使用#0)获取函数本身,并使用/. v:2 :> nextFib[v]将该函数中的数字替换为下一个函数。但是,nextFib在这个阶段不会得到评估,所以我们不会在源代码中得到新的数字。在搜索了一段时间,找出如何强制立即评估,我找到了在Mathematica.SE上发表这篇伟大的文章。“标准”技术使用一个强制求值的With块,但是WReach的第二个答案包含了一个较短的选项,它使用没有文档的内置RuleCondition,这也强制进行评估。
我们计算下一个斐波那契数的方法是利用连续数的比率大约是黄金比1.618.这是精确到四舍五入的。因此,我们不需要跟踪最后两个数字,只需简单地执行Round[GoldenRatio v]。这将永远不会失去精度,因为Mathematica的GoldenRation是一个符号值,因此Round总是可以计算一个精确的结果。
总结如下:
... #0 ... &一个未命名的函数,其中#0引用函数对象本身。
... /. v:2 :> ...在函数的表达式树中找到一个2 (当然,这个2只匹配自己),调用它为v,然后用.
... RuleCondition[Round[GoldenRatio v]]..。下一个斐波那契数。
ToString[...]并将结果表达式树转换为其字符串表示形式。
发布于 2017-05-08 09:47:35
发布于 2017-05-08 09:52:59
a=b=1
while a<2:a,b=b,a+b
s='a=b=1\nwhile a<%i:a,b=b,a+b\ns=%r;print(s%%(b,s))';print(s%(b,s))显然是马丁·安德的CJam答案的分叉。
https://codegolf.stackexchange.com/questions/119542
复制相似问题