APL(158个字符,得分= 4)
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
我在这里使用Dyalog APL。通过将0
表达式的末尾和字符串的末尾(之前'''
)相加(0后跟一个空格),可以将循环数增加一。循环长度为(# 0's) + 1
,表达式的长度为150 + 4*(cycle length))
。假设我们永远永远添加零,则分数为Limit[(150 + 4*n)/(n - 1), n -> Infinity] = 4
,其中n
为周期长度。
这是一个循环长度为6的示例:
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0
0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0
0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0
0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0
0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0
0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0
0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0
0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1
0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 0 0 0 0
192个字符,得分= 2
'''{2≠⍴⍺:¯3⌽(2×1+⍴⍺)⍴(1+⍴⍺)⍴⍺ ⋄ a←⊃2⌷⍺ ⋄ ⍵=0:¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a⋄(-4+⌊10⍟⊃⍺)⌽(2×1+⍴a)⍴(1+⍴a)⍴a}01'''{2≠⍴⍺:¯3⌽(2×1+⍴⍺)⍴(1+⍴⍺)⍴⍺⋄a←⊃2⌷⍺⋄⍵=0:¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a⋄(-4+⌊10⍟⊃⍺)⌽(2×1+⍴a)⍴(1+⍴a)⍴a}01
根据实现的不同,一个失败点可能是字符串前缀的整数太大。但是,从理论上讲,我们可以通过添加两个字符来添加一个循环- 1
在字符串的末尾(在之前'''
)和1
在整行的末尾添加一个字符。
200个字符,得分= 1
'''{a←{2=⍴⍵:⊃2⌷⍵⋄⍵}⍺⋄(⍺{⍵=9:⍬⋄⍕1+{2=⍴⍵:10×⊃⍵⋄0}⍺}⍵),(¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a),⍺{⍵=9:(⍕9),⍕⊃⍺⋄⍕⌊⍵÷10}⍵}'''{a←{2=⍴⍵:⊃2⌷⍵⋄⍵}⍺⋄(⍺{⍵=9:⍬⋄⍕1+{2=⍴⍵:10×⊃⍵⋄0}⍺}⍵),(¯2⌽(2×1+⍴a)⍴(1+⍴a)⍴a),⍺{⍵=9:(⍕9),⍕⊃⍺⋄⍕⌊⍵÷10}⍵}91
我的APL实现默认情况下没有无限精度的整数,因此当整数太大时,该整数将转换为浮点数,从而导致输出错误。因此,这是最挑剔的,但是从理论上讲(无论是手工操作还是使用其他APL解释器),它的得分都应该为1。只需1
在表达式的末尾添加a ,就可以得到另一个循环。
概述(带有较短的奎因)
我将概述第一个版本,因为我认为这可能是最容易理解的版本。但是,在处理该版本之前,我们将考虑APL中的一个简单方法:
1⌽22⍴11⍴'''1⌽22⍴11⍴'''
我发现理解某些APL表达式的最好方法之一是查看整个运算符/函数级联的输出。APL中的所有运算符和函数都是右关联的,并且具有相同的优先级,因此从右到左是这样的:
'''1⌽22⍴11⍴'''
:这只是一个字符串文字(字符列表)。''
是APL转义单引号的方式。输出:'1⌽22⍴11⍴'
。
11⍴'''1⌽22⍴11⍴'''
:这里,我们将(⍴
)整形为length的字符串11
。由于字符串的长度小于11,因此5⍴'abc'
将对其进行重复(即会产生'abcab'
)。输出:'1⌽22⍴11⍴''
。因此,我们现在在末尾有两个引号-我们到了!
22⍴11⍴'''1⌽22⍴11⍴'''
:同样,我们现在将之前的输出重塑为length 22
。输出:'1⌽22⍴11⍴'''1⌽22⍴11⍴''
。我们快到了-我们只需要将第一个单引号移到末尾。
1⌽22⍴11⍴'''1⌽22⍴11⍴'''
:在这里,我们将⌽
字符列表旋转()1
。这会将字符串的第一个字符移到末尾。再举一个例子,2⌽'abcdef'
return 'cdefab'
。输出:1⌽22⍴11⍴'''1⌽22⍴11⍴'''
。
旋转奎
那个短的奎因是我们旋转奎因的主要基础。现在,考虑到这一点,让我们看一下我们的方法:
'''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0
{ ... }
定义一个未命名的函数,我们将在该函数中进行工作。请注意,APL中的函数带有一个右参数(由表示⍵
)和一个可选的左参数(由⍺
(think infix)表示)。我们想同时向我们的Quine字符串和一些东西提供这个功能,以帮助我们创建任意数量的循环。为了使自己(以及任何想要添加循环的人)更轻松,我们将quine字符串作为左参数。因此,正确的参数是放置循环列表的位置。由空格分隔的2个或更多项目创建一个列表,因此在此示例中,我们有2个元素的列表,其中包含a 1
和a 0
。
我们可以看到该函数看起来与以前的方法相似。我们以前有相同的...⌽...⍴...⍴...
表格。很好-我们至少了解得这么多!让我们更深入地研究椭圆,从最后一个开始⍴
:⊃,/(~^/¨⍺=0)/⍺
。
- 如您在上面的示例中看到的那样,我们在字符串的右边添加0前缀,并在每次迭代时添加一个;但是我们现在不在乎那些。我们只想要字符串!
- 首先,请考虑括号中的内容。(顺便说一下,他们像大多数其他语言一样分组。)
⍺=0
返回一个列表,在这种情况下,列表的形状与相同⍺
,如果其中的每个元素均等于,则将其中的每个元素⍺
替换1
为0
,0
否则为。这是递归执行的;因此,如果我们有一个字符列表的列表,则将对各个字符进行0测试,您将获得一个二进制值列表的列表。
- 因此,如果
⍺
仅由我们的字符串组成,我们将返回一个0列表。否则,我们的left参数的前缀为0(例如0 0 0 'quinestring'
),因此它是一个由0和另一个列表(我们的字符串)组成的列表。然后我们的输出看起来像1 1 1 <sub-list of zeros>
。
^/¨⍺=0
:我们将派生函数应用到的每个()元素^/
,该函数/
使用逻辑AND(^
)函数来减少()。这是为了平整零的子列表,以便我们可以将Quine字符串视为一个二进制值。考虑前面的示例,输出为。¨
⍺=0
1 1 1 0
~
:我们不对之前的每个值进行二进制处理(例如,返回0 0 0 1
)。
(~^/¨⍺=0)/⍺
:对于中的每个元素⍺
,我们将其复制(/
)由左参数中相应元素给出的次数。这样就消除了所有的0,只剩下我们的quine字符串。
⊃,/
是一些必要的文书工作,可通过使用串联函数(,
)减少结果来确保获得平坦的字符列表。如果输入已经是一个扁平化的列表(即,主函数的左参数仅是字符串),我们将得到一个包含该列表的1元素列表。在另一种情况下,当我们有一个由字符串的子列表组成的列表时,我们又得到了相同的东西(一个带有子列表的列表)。然后⊃
,我们解压缩此(),只给我们列表的第一个元素(即字符的子列表)。这似乎没有必要,但是否则我们将尝试重塑1元素列表!
接下来,我们在括号内查看为第一次重塑给出的长度:
⍺,⍵
:我们将正确的参数连接到第一个参数
⊃,/⍺,⍵
:与以前相同-整理列表。
+/0=⊃,/⍺,⍵
:/
使用加法(+
)函数通过减少()来累加列表中的零个数。
2×+/0=⊃,/⍺,⍵
:将该数字乘以2。
z←2×+/0=⊃,/⍺,⍵
:将(←
)结果分配给变量z
。回顾一下,z
现在是在左右参数中找到的零的数量的两倍。
77+z←2×+/0=⊃,/⍺,⍵
:然后77
,对于quine字符串中的字符,我们添加,忽略后面的空格1
。像最初的quine示例一样,我们在字符串的长度上加1以得到另一个单引号。
- 在此示例中,此重塑的输出为:
'{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 ''
紧随其后的重塑的论点很简单,它反映了短提包(2倍于第一次重塑的长度)。现在我们的输出是:
'{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 '''{(((3+z)×^/⍵)-5+2×+/+/¨⍺=0)⌽(2×77+z)⍴(77+z←2×+/0=⊃,/⍺,⍵)⍴⊃,/(~^/¨⍺=0)/⍺}1 0 ''
现在进行最后一步,在这里我们计算旋转输出字符串的程度:
- 正如您通过查看先前的输出所看到的,我们希望将其旋转回去(负数),以将2个最终报价引到开头。因为我们也希望一个
0
(和另一个空格)移动到开头,所以我们想将它再旋转3个字符。
+/+/¨⍺=0
:在左参数中加零的数量。第一个(从右侧开始)对+/¨
每个元素的计数(即,子列表或仅是整数)+/
求和,第二个给我们该结果列表的总和。
5+2×+/+/¨⍺=0
:乘以2(也可以旋转空格),然后加5(我们之前得出的结果)。
- 现在,我们从左边的参数中减去前一个值,
-
以处理循环结束时的情况:
(3+z)×^/⍵
:和正确参数中的所有元素一起看我们是否到达了end(1
),然后乘以3+z
。
我们完成了!