Mini-Flak,6851113循环
该程序(字面意思)
我知道大多数人不太希望Mini-Flak quin使用不可打印的字符,甚至使用多字节字符(使编码有意义)。但是,这种方法确实可行,并且不可打印的内容与方法的大小(93919个字符编码为UTF-8的102646字节)相结合,使得将程序放入此帖子中相当困难。
但是,该程序非常重复,因此压缩效果非常好。为了使整个程序在字面上可以从Stack Exchange获得,在可折叠的后面隐藏了xxd
一个gzip
完整版本的-压缩版本的可逆十六进制转储:
00000000: 1f8b 0808 bea3 045c 0203 7175 696e 652e .......\..quine.
00000010: 6d69 6e69 666c 616b 00ed d9db 6a13 4118 miniflak....j.A.
00000020: 0060 2f8b f808 0d64 a1c1 1dc8 4202 c973 .`/....d....B..s
00000030: 4829 4524 0409 22e2 5529 a194 1242 1129 H)E$..".U)...B.)
00000040: d2d7 ca93 f9cf 4c4c d45b 9536 e6db 6967 ......LL.[.6..ig
00000050: 770e 3bc9 ffed eca9 edb7 b1a4 9ad2 6a1d w.;...........j.
00000060: bfab 75db c6c6 6c5f 3d4f a5a6 8da6 dcd8 ..u...l_=O......
00000070: 465b d4a5 5a28 4bd9 719d 727b aa79 f9c9 F[..Z(K.q.r{.y..
00000080: 43b6 b9d7 8b17 cd45 7f79 d3f4 fb65 7519 C......E.y...eu.
00000090: 59ac 9a65 bfdf 8f86 e6b2 69a2 bc5c 4675 Y..e......i..\Fu
000000a0: d4e4 bcd9 5637 17b9 7099 9b73 7dd3 fcb2 ....V7..p..s}...
000000b0: 4773 b9bc e9bd b9ba 3eed 9df7 aeaf 229d Gs......>.....".
000000c0: e6ed 5eae 3aef 9d46 21b2 5e4d bd28 942e ..^.:..F!.^M.(..
000000d0: 6917 d71f a6bf 348c 819f 6260 dfd9 77fe i.....4...b`..w.
000000e0: df86 3e84 74e4 e19b b70e 9af0 111c fa0d ..>.t...........
000000f0: d29c 75ab 21e3 71d7 77f6 9d8f f902 6db2 ..u.!.q.w.....m.
00000100: b8e1 0adf e9e0 9009 1f81 f011 18d8 1b33 ...............3
00000110: 72af 762e aac2 4760 6003 1bd8 698c c043 r.v...G``...i..C
00000120: 8879 6bde 9245 207c 04ae 5ce6 2d02 e1bb .yk..E |..\.-...
00000130: 7291 4540 57f8 fe0d 6546 f89b a70b 8da9 r.E@W...eF......
00000140: f5e7 03ff 8b8f 3ad6 a367 d60b f980 679d ......:..g....g.
00000150: d3d6 1c16 f2ff a767 e608 57c8 c27d c697 .......g..W..}..
00000160: 4207 c140 9e47 9d57 2e50 6e8e c215 b270 B..@.G.W.Pn....p
00000170: bdf6 9926 9e47 9d05 ce02 0ff0 5ea7 109a ...&.G......^...
00000180: 8ba6 b5db 880b 970b 9749 2864 47d8 1b92 .........I(dG...
00000190: 39e7 9aec 8f0e 9e93 117a 6773 b710 ae53 9........zgs...S
000001a0: cd01 17ee b30e d9c1 15e6 6186 7a5c dc26 ..........a.z\.&
000001b0: 9750 1d51 610a d594 10ea f3be 4b7a 2c37 .P.Qa.......Kz,7
000001c0: 2f85 7a14 8fc4 a696 304d 4bdf c143 8db3 /.z.....0MK..C..
000001d0: d785 8a96 3085 2acc 274a a358 c635 8d37 ....0.*.'J.X.5.7
000001e0: 5f37 0f25 8ff5 6854 4a1f f6ad 1fc7 dbba _7.%..hTJ.......
000001f0: 51ed 517b 8da2 4b34 8d77 e5b2 ec46 7a18 Q.Q{..K4.w...Fz.
00000200: ffe8 3ade 6fed b2f2 99a3 bae3 c949 9ab5 ..:.o........I..
00000210: ab75 d897 d53c b258 a555 1b07 63d6 a679 .u...<.X.U..c..y
00000220: 4a51 5ead a23a 6a72 9eb6 d569 960b f3dc JQ^..:jr...i....
00000230: 9ceb 53fa 658f 345f ad07 6f6f efce 06ef ..S.e.4_..oo....
00000240: 0677 b791 cef2 f620 57bd 1b9c 4521 b241 .w..... W...E!.A
00000250: 4d83 2894 2eaf a140 8102 050a 1428 50a0 M.(....@.....(P.
00000260: 4081 0205 0a14 2850 a040 8102 050a 1428 @.....(P.@.....(
00000270: 50a0 4081 0205 0a14 2850 a040 8102 050a P.@.....(P.@....
00000280: 1428 50a0 4081 0205 0a14 2850 a040 8102 .(P.@.....(P.@..
00000290: 050a 1428 50a0 4081 0205 0a14 2850 a040 ...(P.@.....(P.@
000002a0: 8102 050a 1428 50a0 4081 0205 0a14 2850 .....(P.@.....(P
000002b0: a040 8102 050a 1428 50a0 4081 0205 0a14 .@.....(P.@.....
000002c0: 2850 a040 8102 050a 1428 50a0 4081 0205 (P.@.....(P.@...
000002d0: 0a14 2850 a040 8102 050a 1428 50a0 4081 ..(P.@.....(P.@.
000002e0: 0205 0a14 2850 a040 8102 050a 1428 50a0 ....(P.@.....(P.
000002f0: 4081 0205 0a14 2850 a040 8102 050a 1428 @.....(P.@.....(
00000300: 50a0 4081 0205 0a14 2850 a040 8102 050a P.@.....(P.@....
00000310: 1428 50a0 4081 0205 0a14 2850 a040 8102 .(P.@.....(P.@..
00000320: 050a 1428 50a0 4081 0205 0a14 2850 a040 ...(P.@.....(P.@
00000330: 8102 050a 1428 50a0 4081 0205 0a14 2850 .....(P.@.....(P
00000340: a040 8102 050a 1428 50a0 4081 0205 0a14 .@.....(P.@.....
00000350: 2850 a040 8102 050a 1428 50a0 4081 0205 (P.@.....(P.@...
00000360: 0a14 2850 a040 8102 050a 1428 50a0 4081 ..(P.@.....(P.@.
00000370: 0205 0a14 2850 a01c 14ca 7012 cbb4 a6e9 ....(P....p.....
00000380: e6db e6b1 e4b1 9e4c 4ae9 d3be f5f3 745b .......LJ.....t[
00000390: 37a9 3d6a af49 7489 a6e9 ae5c 96dd 488f 7.=j.It....\..H.
000003a0: d31f 5da7 fbad 5d56 3e73 5277 7cf5 aa7b ..]...]V>sRw|..{
000003b0: 3fbc df7c e986 c3ba 5ee4 3c6f 74f7 c3e1 ?..|....^.<ot...
000003c0: 301a bb45 d795 9afb fbdc 1495 65d5 6d9b 0..E........e.m.
000003d0: baf7 a5b4 a87d 4a5b d7fd b667 b788 ec27 .....}J[...g...'
000003e0: c5d8 28bc b96a 9eda 7a50 524d 290a a5cb ..(..j..zPRM)...
000003f0: cbef 38cb c3ad f690 0100 ..8.......
(是的,它是如此重复,以至于压缩后您甚至可以看到重复的片段)。
问题是:“我也强烈建议您不要在TIO中运行程序。TIO不仅比台式机解释器慢,而且还会在大约一分钟内超时。如果有人设法得分足够低而无法运行,那将给人留下深刻的印象。他们的程序在TIO超时之前。” 我可以做到的!使用Ruby解释器,在TIO上运行大约需要20秒:在线尝试!
该程序(可读)
现在,我提供了计算机可以读取的程序版本,让我们尝试一下人类可以读取的版本。我已经将构成五线组的字节转换为代码页437(如果设置了高位)或Unicode控制图片(如果它们是ASCII控制代码),则添加了空格(任何先前存在的空格都转换为控制图片) ),使用语法进行游程编码«string×length»
,并删除了一些数据繁重的位:
␠
(((()()()()){}))
{{}
(({})[(()()()())])
(({})(
{{}{}((()[()]))}{}
(((((((({})){}){}{})){}{}){}){}())
{
({}(
(␀␀!S␠su! … many more comment characters … oq␝qoqoq)
(«()×35» («()×44» («()×44» («()×44» («()×44» («()×45»
… much more data encoded the same way …
(«()×117»(«()×115»(«()×117»
«000010101011┬â┬ … many more comment characters … ┬â0┬â┬à00␈␈
)[({})(
([({})]({}{}))
{
((()[()]))
}{}
{
{
({}(((({}())[()])))[{}()])
}{}
(({}))
((()[()]))
}{}
)]{}
%Wwy$%Y%ywywy$wy$%%%WwyY%$$wy%$$%$%$%$%%wy%ywywy'×almost 241»
,444454545455┬ç┬ … many more comment characters … -a--┬ü␡┬ü-a␡┬ü
)[{}()])
}{}
{}({}())
)[{}])
(({})(()()()()){})
}{}{}␊
(“几乎241”是因为第241个副本缺少结尾'
,但与其他240个相同)。
说明
关于评论
首先要解释的是,那些不是Mini-Flak命令的不可打印字符和其他垃圾怎么处理?您可能会认为,将注释添加到包装盒只会使事情变得更难,但这是一场速度竞赛(而非大小竞赛),这意味着注释不会损害程序的速度。同时,Brain-Flak和Mini-Flak只是将堆栈中的内容转储到标准输出中。如果您必须确保堆栈仅包含组成程序命令的字符,则必须花一些时间清理堆栈。实际上,Brain-Flak会忽略大多数字符,因此只要我们确保垃圾堆栈元素不是有效的Brain-Flak命令(使之成为Brain-Flak / Mini-Flak多色图),并且不是负数或在外部在Unicode范围内,我们可以将它们保留在堆栈上,允许它们输出,然后将相同字符放在程序中的相同位置以保留quine属性。
我们可以利用一种特别重要的方法来利用这一点。quine通过使用长数据字符串来工作,基本上,quine的所有输出都是通过以各种方式格式化数据字符串来产生的。尽管程序有多个片段,但是只有一个数据字符串;因此我们需要能够使用相同的数据字符串来打印程序的不同部分。“垃圾数据无关紧要”的技巧使我们能够以一种非常简单的方式进行操作。我们通过在其ASCII代码中添加或减去一个值来将组成程序的字符存储在数据字符串中。具体来说,构成程序开始的字符以ASCII码+ 4的形式存储,构成该节的字符以ASCII码− 4重复几乎241次。数据字符串的每个字符都有偏移量;例如,如果我们在每个字符代码上添加4,则将其打印出来,则得到重复部分的重复,并在前后加上一些注释。(这些注释只是程序的其他部分,字符代码进行了移位,以使它们不构成任何有效的Brain-Flak命令,因为添加了错误的偏移量。我们必须避开Brain-Flak命令,而不仅仅是Mini- Flak命令,以避免违反问题的受限来源部分;偏移量的选择旨在确保这一点。)
由于这个注释技巧,我们实际上只需要能够以两种不同的方式输出格式化的数据字符串:a)与源代码中的编码方式相同,b)作为字符代码,并在每个代码中添加指定的偏移量。这是一个极大的简化,使增加的长度完全值得。
程序结构
该程序包括四个部分:简介,数据字符串,数据字符串格式化程序和结尾。intro和outro基本上负责循环运行数据字符串及其格式化程序,每次都指定适当的格式(即,是编码还是偏移量,以及使用什么偏移量)。数据字符串只是数据,并且是quine的唯一部分,在该部分中,没有在数据字符串中按字面值指定组成字符的字符串(这样做显然是不可能的,因为它必须比自身更长);因此,它以一种非常容易从自身再生的方式编写。数据字符串格式化程序由241个几乎相同的部分组成,每个部分格式化数据字符串中241个中的特定数据。
程序的每个部分都可以通过数据字符串及其格式化程序生成,如下所示:
- 要产生结果,请使用偏移量+8格式化数据字符串
- 要生成数据字符串格式化程序,请使用偏移量+4格式化数据字符串241次
- 要生成数据字符串,请通过将其编码为源格式来格式化数据字符串
- 要制作简介,请使用偏移量-4格式化数据字符串
因此,我们要做的就是查看程序的这些部分如何工作。
数据字符串
(«()×35» («()×44» («()×44» («()×44» («()×44» («()×45» …
我们需要对数据字符串进行简单编码,因为我们必须能够反转Mini-Flak代码中的编码。您再简单不过了!
这种方法背后的关键思想(除了注释技巧)是要注意的是,基本上只有一个地方可以存储大量数据:程序源的各种嵌套级别中的“命令返回值之和”。(这通常称为第三叠,尽管Mini-Flak没有第二个堆栈,所以在Mini-Flak上下文中“工作堆栈”可能是一个更好的名称。)用于存储数据的其他可能性是主堆栈/第一个堆栈(不起作用)因为那是我们的输出所必须去的,并且我们不能以远距离有效的方式将输出移到存储之外),并在单个堆栈元素中将其编码成bignum(这不适用于此问题,因为它花费了指数时间)从中提取数据);当您消除这些位置时,工作堆栈是唯一剩余的位置。
为了将数据“存储”在该堆栈上,我们使用不平衡命令(在本例中为(…)
命令的前半部分),稍后将在数据字符串格式化程序中对它们进行平衡。每次我们在格式化程序中关闭这些命令之一时,它将推送从数据字符串获取的数据之和,以及在格式化程序中处于该嵌套级别的所有命令的返回值;我们可以确保后者加为零,因此格式化程序仅查看从数据字符串获取的单个值。
格式非常简单:(
,后跟的n个副本()
,其中n是我们要存储的数字。(请注意,这意味着我们只能存储非负数,并且数据字符串的最后一个元素必须为正。)
关于数据字符串的一个有点不直观的地方是它的顺序。数据字符串的“开始”是靠近程序开始的结尾,即最外层的嵌套级别;这部分最后格式化(因为格式化程序从最内层嵌套层到最外层嵌套层运行)。但是,尽管最后格式化了,但还是先打印了,因为Mini-Flak解释器最后打印了被压入堆栈的值。相同的原则适用于整个程序。我们需要首先格式化结尾,然后格式化数据字符串格式化程序,然后格式化数据字符串,然后格式化序言,即它们在程序中存储顺序的相反顺序。
数据字符串格式化程序
)[({})(
([({})]({}{}))
{
((()[()]))
}{}
{
{
({}(((({}())[()])))[{}()])
}{}
(({}))
((()[()]))
}{}
)]{}
数据字符串格式化程序由241个部分组成,每个部分具有相同的代码(一个部分的注释略有不同),每个部分都格式化数据字符串的一个特定字符。(我们不能在此处使用循环:我们需要一个不平衡的变量,)
才能通过匹配它的不平衡变量来读取数据字符串(
,而且我们不能将其中之一放入{…}
存在的唯一循环形式的循环中。因此,我们“展开”格式化程序,然后简单地进行简介/输出操作即可输出具有格式化程序偏移量241倍的数据字符串。)
)[({})( … )]{}
格式化程序元素的最外层部分读取数据字符串的一个元素;数据字符串编码的简单性导致读取它时有点复杂。首先关闭(…)
数据字符串中不匹配的内容,然后取反([…]
)两个值:刚从数据字符串(({})
)中读取的数据和程序其余部分的返回值。我们使用复制复制其余formatter元素的返回值,(…)
并使用将复制的内容添加到否定版本中{}
。最终结果是数据字符串元素和格式化程序元素的返回值加在一起是基准减去基准减去返回值加上返回值或0;这是使下一个数据字符串元素产生正确值所必需的。
([({})]({}{}))
格式化程序使用顶部堆栈元素来知道它处于哪种模式(0 =数据字符串格式的格式,其他任何值=输出的偏移量)。但是,仅读取数据字符串,数据就位于堆栈格式的顶部,我们希望它们反过来。这个代码是脑高射炮交换代码的一较短的变型中,考虑一个上述b到b以上一个 + b ; 它不仅更短,而且(在此特定情况下)更有用,因为在b为0 时将b加到a的副作用并不成问题,而当b不为0时,它将为我们进行偏移计算。
{
((()[()]))
}{}
{
…
((()[()]))
}{}
Brain-Flak仅具有一个控制流结构,因此,如果我们需要while
循环以外的任何其他功能,则需要进行一些工作。这是一个“否定”结构;如果堆栈顶部为0,则将其删除,否则将0置于堆栈顶部。(它的工作原理非常简单:只要堆栈顶部没有0,就两次将1-1压入堆栈;完成后,弹出顶部堆栈元素。)
如此处所示,可以将代码放置在求反结构内。仅当栈顶为非零时,代码才运行;因此,如果我们有两个否定结构,则假设顶部的两个堆栈元素都不都是零,它们将互相抵消,但是第一个结构内部的任何代码仅在顶部堆栈元素为非零且内部代码仅当顶部堆栈元素为零时,第二个结构才会运行。换句话说,这等效于if-then-else语句。
在格式为非零的情况下运行的“ then”子句中,我们实际上没有任何关系。我们想要的是将数据和偏移量压入主堆栈(以便可以在程序末尾输出),但是它已经存在了。因此,我们只需要处理以源形式编码数据字符串元素的情况。
{
({}(((({}())[()])))[{}()])
}{}
(({}))
这是我们的方法。该{({}( … )[{}()])}{}
结构应该熟悉为具有特定迭代次数的循环(通过将循环计数器移至工作堆栈并将其保存在其中来进行工作;它对任何其他代码都是安全的,因为对工作堆栈的访问与程序的嵌套级别)。循环的主体为((({}())[()]))
,它复制了顶部堆栈元素的三个副本,并向最低的堆栈元素添加了1。换句话说,它将堆栈顶部的40转换为41之上40之上的40,或者将其视为ASCII (
转换为(()
; 重复运行这将使(
成(()
成(()()
成(()()()
等,因而产生我们的数据串一个简单的方法(假设有一个(
堆栈顶部的话)。
循环完成后,请(({}))
复制堆栈的顶部(以便现在开始((()…
而不是开始(()…
。)(
,数据字符串格式化程序的下一个副本将使用前导来格式化下一个字符(将其扩展为(()(()…
然后(()()(()…
,依此类推,因此这会(
在数据字符串中生成分隔符)。
%Wwy$%Y%ywywy$wy$%%%WwyY%$$wy%$$%$%$%$%%wy%ywywy'
数据字符串格式化程序的最后一点是令人感兴趣的。好的,因此大多数情况下,这只是向下移位了4个代码点;但是,最后的撇号可能看起来不合适。'
(代码点39)将转换为+
(代码点43),这不是Brain-Flak命令,因此您可能已经猜到它存在于其他目的。
这是因为数据字符串格式化程序希望(
堆栈中已经有一个(它在任何地方都不包含文字40)。的'
实际上是在重复开始以构成数据字符串格式化程序的块的开始,而不是结尾,因此,在将数据字符串格式化程序的字符推入堆栈后(代码即将移至打印数据字符串)本身,outro将堆栈顶部的39调整为40,以供格式化程序使用(这次正在运行的格式化程序本身,而不是其在源代码中的表示形式)以使用它。这就是为什么我们有“几乎241”份格式化程序的原因;第一个副本缺少其第一个字符。而且,单引号这个字符是数据字符串中仅有的三个与程序中某处的Mini-Flak代码不对应的字符之一;它纯粹是作为提供常量的一种方法。
简介与结尾
(((()()()()){}))
{{}
(({})[(()()()())])
(({})(
{{}{}((()[()]))}{}
(((((((({})){}){}{})){}{}){}){}())
{
({}(
(␀␀!S␠su! … many more comment characters … oq␝qoqoq)
…
)[{}()])
}{}
{}({}())
)[{}])
(({})(()()()()){})
}{}{}␊
简介和结尾在概念上是程序的同一部分;我们进行区分的唯一原因是,需要在输出数据字符串及其格式器之前输出outro(以便在其后面打印),而在其后面输出intro(在它们之前打印)。
(((()()()()){}))
我们首先将两个8的副本放在堆栈上。这是第一次迭代的偏移量。第二个副本是因为主循环期望偏移量之上的堆栈顶部有一个垃圾元素,而决定是否存在主循环的测试将其遗漏了,因此我们需要在其中放置一个垃圾元素,以便它并没有丢弃我们真正想要的元素;副本是做到这一点的最好方法(因此输出最快)。
数字8的其他表示形式不超过此数字。但是,当寻求最快的代码时,这绝对是最佳选择。一方面,使用()()()()
速度比说更快(()()){}
,因为尽管两者都长8个字符,但前者的循环速度更快,因为(…)
被算作2个循环,但()
只算作一个循环。相比于一个大得多的考虑节省一个周期可以忽略不计喹,虽然:(
和)
具有比码点低得多的{
和}
,所以产生用于他们的数据片段将要快得多(和数据片段将占用较少的空间中的代码,太)。
{{} … }{}{}
主循环。这不计算迭代次数(这是一个while
循环,而不是一个for
循环,并使用测试进行爆发)。一旦退出,我们将丢弃顶部的两个堆栈元素。最上面的元素是一个无害的0,但是下面的元素将是“下次迭代使用的格式”,它(是一个负偏移量)是一个负数,并且当Mini的堆栈上有任何负数时-Flak程序退出,解释器尝试输出它们时崩溃。
因为此循环使用显式测试进行突破,所以该测试的结果将保留在堆栈中,因此我们将其丢弃为第一件事(其值无用)。
(({})[(()()()())])
该代码将4和f -4 推入堆栈元素f的上方,同时将该元素保留在原位。我们正在预先计算下一次迭代的格式(同时我们拥有常数4),同时为程序的后几部分同时将堆栈设置为正确的顺序:我们将使用f作为此迭代,在此之前需要4。
(({})( … )[{}])
这会将f − 4 的副本保存在工作堆栈中,以便我们可以将其用于下一次迭代。(f的值到那时仍会存在,但是它将在堆栈中处于一个尴尬的位置,即使我们可以将其操纵到正确的位置,我们也必须花费一些周期从中减去4,并循环打印代码以执行此减法操作。现在简单地存储它就容易得多。)
{{}{}((()[()]))}{}
测试偏移量是否为4(即f − 4为0)。如果是这样,我们将打印数据字符串格式化程序,因此我们需要运行241次数据字符串及其格式化程序,而不是在此偏移量运行一次。代码非常简单:如果f -4为非零,则 用一对零替换f -4和4本身;否则,将f -4和4本身替换为零。然后,无论哪种情况,都弹出顶部堆栈元素。现在,我们在堆栈上有一个高于f的数字,可以是4(如果要将此迭代打印241次)或0(如果要仅打印一次)。
(
((((((({})){}){}{})){}{}){}){}
()
)
这是一种有趣的Brain-Flak / Mini-Flak常数;这里的长线代表数字60。您可能会因为缺乏而感到困惑,()
通常在Brain-Flak常数中到处都是;这不是常规数字,而是教堂数字,它会将数字解释为重复运算。例如,此处显示的教堂数字60代表60个输入副本,并将它们全部组合为一个值。在Brain-Flak中,我们可以组合的唯一东西是正数,再加上加法运算,所以我们最终将堆栈顶部的60个副本相加,然后将堆栈顶部乘以60。
附带说明一下,您可以使用Underload数字查找器,它以Underload语法生成教堂数字,也可以在Mini-Flak中找到合适的数字。欠载数字(非零)使用操作“重复的顶部堆栈元素” :
和“组合顶部的两个堆栈元素” *
;无论是在脑高射炮存在这些行动,所以你只是翻译:
给)
,*
给{}
,前置{}
,并添加足以(
在开始时平衡(这是使用主堆栈和工作组的一个奇怪的组合,但它的工作原理)。
这个特定的代码片段使用教堂数字60(实际上是“乘以60”片段)以及一个增量来生成表达式60 x +1。因此,如果我们在上一步中得到4,则将为我们提供一个值241,或者如果我们有一个0,我们只得到1的值,即,这正确地计算了我们需要的迭代次数。
选择241并非偶然。它是一个被选择为a)大约等于程序最终结束的长度的值,并且b)1大于整数的4倍。在这种情况下,整数60表示的教堂数字往往更短,因为您在复制因子方面更具灵活性。该程序稍后包含填充以使长度精确到241。
{
({}(
…
)[{}()])
}{}
这是一个for循环,就像前面看到的那样,该循环只是简单地在其中运行代码几次,使其次数等于主堆栈的顶部(它消耗;循环计数器本身存储在工作堆栈中,但是绑定到程序的嵌套级别,因此,除了for循环本身之外,其他任何东西都无法与之交互)。这实际上运行了数据字符串及其格式化程序1或241次,并且由于我们现在从主堆栈中弹出了用于控制流计算的所有值,因此我们可以在其顶部使用格式,以备要使用的格式化程序。
(␀␀!S␠su! … many more comment characters … oq␝qoqoq)
这里的评论并非完全没有兴趣。一方面,有两个Brain-Flak命令;所述)
在端部被自然作为节目工作的各部分之间的过渡,故该方式的副作用产生(
在开始手工加入到平衡它(尽管注释内的长度,把一个注释内一个()
命令仍然是一个()
命令,所以它所做的只是加1数据串的返回值和它的格式,这东西for循环完全忽略)。
更值得注意的是,注释开头的NUL字符显然没有任何偏移(即使+8和-4之间的差异不足以将a (
转换为NUL)。这些都是纯填充,可将239个元素的数据字符串最多增加241个元素(它们很容易为自己付出:在计算所需的迭代次数时,生成1 vs. 239而不是1 vs. 241将花费两个以上的字节。 )。NUL用作填充字符,因为它具有最低的代码点(使数据字符串的源代码更短,因此输出速度更快)。
{}({}())
删除最上面的堆栈元素(我们正在使用的格式),在下一个元素(要格式化的程序部分的最后一个字符,即要打印的第一个字符)后面加1。我们不再需要旧的格式(新的格式隐藏在工作堆栈中);并且该增量在大多数情况下是无害的,并且'
将数据字符串格式化程序的源表示形式的一端更改为a (
(这是堆栈上的要求,下次运行该格式化程序时,才需要格式化数据字符串本身)。我们需要在outro或intro中进行这样的转换,因为强制每个数据字符串格式化程序元素(
都将使其变得更加复杂(因为我们需要先关闭(
,然后再撤消其作用),并且我们会以某种方式需要产生一个额外的(
地方,因为我们只有差不多 241格式的副本,而不是所有241(所以它是最好的,像无害的字符'
是一个缺少)。
(({})(()()()()){})
最后,进行循环退出测试。主堆栈的当前顶部是下一次迭代所需的格式(刚从工作堆栈中返回)。这将它复制并添加8;结果值将在下次循环时被丢弃。但是,如果仅打印简介,则偏移量为-4,因此“下一次迭代”的偏移量为-8;-8 + 8为0,因此循环将退出,而不是随后继续进行迭代。