Mini-Flak、6851113サイクル
プログラム(文字通り)
ほとんどの人は、Mini-Flakクインが印刷できない文字やマルチバイト文字を使用することを期待していない可能性が高いことを知っています(エンコードを適切にします)。しかし、このクインは、クインのサイズ(UTF-8の102646バイトとしてエンコードされた93919文字)と組み合わされて、印刷不可能なものがあるため、プログラムをこの投稿に配置することはかなり困難です。
しかし、このプログラムは非常に反復的であり、そのようなものとして、圧縮本当にうまく。Stack Exchangeからプログラム全体が文字通り利用できるように、以下の折りたたみ可能なものの後ろに隠された完全なクインの圧縮バージョンのxxd
可逆的な16進ダンプがあり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はデスクトップインタープリターよりも遅いだけでなく、約1分でタイムアウトします。 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 / Mini-Flakポリグロットにする)でなく、負でも外側でもない限り、Brain-Flakはほとんどの文字を無視します。 Unicodeの範囲では、スタックにそのまま残して出力できるようにし、プログラム内の同じ場所に同じ文字を配置してquineプロパティを保持できます。
これを利用できる特に重要な方法が1つあります。クインは長いデータ文字列を使用して機能し、基本的にクインからのすべての出力は、データ文字列をさまざまな方法でフォーマットすることによって生成されます。プログラムには複数の部分があるにもかかわらず、データ文字列は1つだけです。そのため、同じデータ文字列を使用してプログラムの異なる部分を印刷できる必要があります。「ジャンクデータは重要ではありません」トリックにより、非常に簡単な方法でこれを行うことができます。ASCIIコードとの間で値を加算または減算して、プログラムを構成する文字をデータ文字列に格納します。具体的には、プログラムの開始を構成する文字はASCIIコード+ 4として格納され、セクションを構成する文字はASCIIコード-4としてほぼ241回繰り返されますオフセット付きのデータ文字列のすべての文字。たとえば、すべての文字コードに4を追加して印刷すると、繰り返しセクションが1回繰り返され、前後にコメントが追加されます。(これらのコメントは、プログラムの他のセクションにすぎず、文字コードがシフトされているため、間違ったオフセットが追加されたため、有効なBrain-Flakコマンドを形成できません。Mini- 質問のソースの制限された部分への違反を避けるためのFlakコマンド。オフセットの選択は、これを保証するために設計されました。
このコメントトリックのため、実際には、2つの異なる方法でフォーマットされたデータ文字列を出力する必要があるだけです。これは非常に単純化されており、追加された長さは完全に価値があります。
プログラム構成
このプログラムは、イントロ、データ文字列、データ文字列フォーマッタ、およびアウトロの4つの部分で構成されています。introとoutroは基本的に、データ文字列とそのフォーマッターをループで実行し、毎回適切な形式(つまり、エンコードするかオフセットするか、使用するオフセット)を指定します。データ文字列は単なるデータであり、それを構成する文字がデータ文字列で文字どおりに指定されていない唯一の部分です(それはそれよりも長くなければならないため、明らかに不可能です); このように、それはそれ自体から再生するのが特に簡単な方法で書かれています。データ文字列フォーマッタは、ほぼ同じ241個の部分で構成され、各部分はデータ文字列の241個から特定のデータをフォーマットします。
プログラムの各部分は、次のようにデータ文字列とそのフォーマッタを介して生成できます。
- outroを生成するには、オフセット+8でデータ文字列をフォーマットします
- データ文字列フォーマッタを生成するには、オフセット+4、241回でデータ文字列をフォーマットします
- データ文字列を生成するには、ソース文字列にエンコードしてデータ文字列をフォーマットします
- イントロを作成するには、オフセット-4でデータ文字列をフォーマットします
そのため、プログラムのこれらの部分がどのように機能するかを調べるだけです。
データ文字列
(«()×35» («()×44» («()×44» («()×44» («()×44» («()×45» …
Mini-Flakコードでエンコードを逆にできるようにする必要があるため、データ文字列のシンプルなエンコードが必要です。あなたはこれよりもはるかに簡単になることはできません!
このコメントの裏にある重要なアイデアは(コメントトリックを除く)、大量のデータを格納できる場所は基本的に1つだけであることに注意することです。プログラムソースのさまざまなネストレベル内の「コマンド戻り値の合計」です。(これは一般に3番目のスタックとして知られています、Mini-Flakには2番目のスタックはありませんが、Mini-Flakコンテキストでは「作業スタック」の方が適切な名前である可能性があります。)データを格納する他の可能性はメイン/最初のスタックですこれは出力が必要な場所であり、リモートで効率的な方法でストレージを超えて出力を移動することはできず、単一のスタック要素でビッグナムにエンコードされるためです(指数関数的な時間がかかるため、この問題には適していません)それからデータを抽出します); これらを削除すると、作業スタックのみが残りの場所になります。
このスタックにデータを「格納」するために、バランスの取れていないコマンド(この場合は(…)
コマンドの前半)を使用します。これは、後でデータ文字列フォーマッタ内でバランスが取られます。フォーマッタ内でこれらのコマンドのいずれかを閉じるたびに、データ文字列から取得したデータの合計と、フォーマッタ内のそのネストレベルのすべてのコマンドの戻り値がプッシュされます。後者がゼロに追加されるようにすることができるため、フォーマッタはデータ文字列から取得した単一の値を単に見るだけです。
形式は非常に単純です:(
、その後にn個のコピーが続きます。()
ここで、nは保存する数値です。(これは、負でない数値のみを保存できることを意味し、データ文字列の最後の要素は正である必要があることに注意してください。)
データ文字列に関する少し直感的でない点は、その順序です。データ文字列の「開始」は、プログラムの開始に近い終了、つまり最も外側のネストレベルです。この部分は最後にフォーマットされます(フォーマッターが最も内側から最も外側のネストレベルまで実行されるため)。しかし、最後にフォーマットされているにもかかわらず、それが取得し印刷最初のスタックにプッシュされた値は、ミニフラックインタプリタにより最後に印刷されているため、第一。同じ原則がプログラム全体に適用されます。最初にoutroをフォーマットし、次にデータ文字列フォーマッター、次にデータ文字列、次にイントロ、つまりプログラムに保存されている順序の逆をフォーマットする必要があります。
データ文字列フォーマッタ
)[({})(
([({})]({}{}))
{
((()[()]))
}{}
{
{
({}(((({}())[()])))[{}()])
}{}
(({}))
((()[()]))
}{}
)]{}
データ文字列フォーマッタは、それぞれが同じコード(1つのセクションはわずかに異なるコメントを持つ)を持つ241個のセクションで構成され、各セクションはデータ文字列の特定の1文字をフォーマットします。(ここではループを使用できませんでした。unbalanced )
を照合してデータ文字列を読み込むには、unbalanced が必要です。ループの(
1つである{…}
ループは、存在する唯一のループです。そのため、代わりに、フォーマッタを展開し、イントロ/アウトロを取得して、フォーマッタのオフセットを含むデータ文字列を241回出力します。)
)[({})( … )]{}
フォーマッタ要素の最も外側の部分は、データ文字列の1つの要素を読み取ります。データ文字列のエンコードが単純であるため、データ文字列の読み取りが少し複雑になります。(…)
データ文字列で一致しないものを閉じて[…]
から、2つの値を否定()します。データ文字列から読み取ったデータ(({})
)とプログラムの残りの戻り値です。フォーマッタ要素の残りの戻り値をで(…)
コピーし、そのコピーを否定バージョンに追加します{}
。最終結果は、データ文字列要素とフォーマッタ要素の戻り値が、データムからデータムから戻り値に戻り値を加えた値、または0になることです。これは、次のデータ文字列要素が正しい値を生成するために必要です。
([({})]({}{}))
フォーマッタは、最上位スタック要素を使用して、どのモードにあるかを認識します(0 =データ文字列フォーマットのフォーマット、その他の値=出力のオフセット)。ただし、データ文字列を読み取っただけで、データはスタック上の形式の一番上にあり、逆方向にデータが必要です。このコードは、撮影脳フラックスワップコードの短い変異体であり、上記BをするB上記 +の B。追加の副作用ためだけでなく、それは短いですが、それは、(この特定のケースでは)また、より便利ですBをする際に問題とならないbが 0である、そしてときbは 0ではない、それは私たちのためにオフセット計算を行います。
{
((()[()]))
}{}
{
…
((()[()]))
}{}
Brain-Flakには制御フロー構造が1つしかないため、while
ループ以外のものが必要な場合は、少し手間がかかります。これは「否定」構造です。スタックの先頭に0がある場合、それを削除します。それ以外の場合は、スタックの先頭に0を配置します。(かなり簡単に動作します:スタックの先頭に0がない限り、スタックに1 − 1を2回プッシュします。完了したら、先頭のスタック要素をポップします。)
ここに見られるように、否定構造内にコードを配置することが可能です。コードは、スタックの最上位がゼロ以外の場合にのみ実行されます。したがって、2つのnegate構造があり、上部の2つのスタック要素が両方ともゼロでないと仮定すると、それらは互いにキャンセルされますが、最初の構造内のコードは、上部のスタック要素がゼロ以外で、 2番目の構造は、一番上のスタック要素がゼロの場合にのみ実行されます。つまり、これはif-then-elseステートメントと同等です。
形式がゼロ以外の場合に実行される「then」節では、実際には何もしません。私たちが望んでいるのは、データ+オフセットをメインスタックにプッシュすることです(そのため、プログラムの最後に出力できるようになります)が、既にそこにあります。したがって、ソース形式でデータ文字列要素をエンコードする場合にのみ対処する必要があります。
{
({}(((({}())[()])))[{}()])
}{}
(({}))
以下にその方法を示します。{({}( … )[{}()])}{}
構造ワーキングスタックにループカウンタを移動させ、そこに保持することによって動作する反復の特定の数(とループとして理解しておく必要があり、作業スタックへのアクセスがに接続されているので、それは、他のコードから安全ですよプログラムのネストレベル)。ループの本体はです((({}())[()]))
。これにより、一番上のスタック要素のコピーが3つ作成され、一番下に1が追加されます。言い換えると、スタックの上の40を、41の上の40の上にある40に変換するか、ASCIIとして表示さ(
れ(()
ます。これを繰り返し実行することになります(
へ(()
へ(()()
へ(()()()
(そこだと仮定し、その上、ひいては我々のデータ列を生成するための簡単な方法で(
、すでにスタックの一番上)。
我々がループして完了したら、(({}))
それは今開始されるように、スタック(のトップを複製する((()…
のではなく(()…
。大手(
次の文字をフォーマットするデータ列フォーマッタの次のコピーで使用されます(それはにそれを拡張します(()(()…
その後(()()(()…
、など(
、データ文字列に区切りが生成されます)。
%Wwy$%Y%ywywy$wy$%%%WwyY%$$wy%$$%$%$%$%%wy%ywywy'
データ文字列フォーマッタには、最後にもう1つ興味があります。OK、だいたいこれは、単に4つのコードポイントを下方にシフトしたアウトロです。ただし、最後のアポストロフィは場違いに見える場合があります。'
(コードポイント39)は+
(コードポイント43)にシフトしますが、これはBrain-Flakコマンドではないため、他の目的で使用されていると推測できます。
これがここにある理由は、データ文字列フォーマッタが(
既にスタック上にあることを予期しているためです(リテラル40はどこにも含まれていません)。の'
実際には、データ文字列フォーマッタの文字がスタックにプッシュされた後、データ文字列フォーマッタを構成するために繰り返されるブロックの先頭にあります(そして、コードはデータ文字列の印刷に移ろうとしています)それ自体)、アウトロは、スタックの上の39を40に調整し、フォーマッター(今回はソースの表現ではなく、実行中のフォーマッター自体)を使用できるようにします。そのため、フォーマッタの「ほぼ241個」のコピーがあります。最初のコピーには最初の文字がありません。そして、その文字であるアポストロフィは、プログラム内のどこかにあるMini-Flakコードに対応していないデータ文字列内の3つの文字のうちの1つです。純粋に定数を提供する方法として存在します。
イントロとアウトロ
(((()()()()){}))
{{}
(({})[(()()()())])
(({})(
{{}{}((()[()]))}{}
(((((((({})){}){}{})){}{}){}){}())
{
({}(
(␀␀!S␠su! … many more comment characters … oq␝qoqoq)
…
)[{}()])
}{}
{}({}())
)[{}])
(({})(()()()()){})
}{}{}␊
イントロとアウトロは、概念的にはプログラムの同じ部分です。区別する唯一の理由は、データ文字列とそのフォーマッタの前にoutroを出力する必要があるため(その後に印刷するため)、イントロはそれらの後に出力する必要がある(前に印刷する)ことです。
(((()()()()){}))
スタックに8個のコピーを2つ置くことから始めます。これは、最初の反復のオフセットです。2番目のコピーは、メインループがオフセットの上のスタックの最上部にジャンクエレメントが存在することを期待し、メインループが存在するかどうかを決定するテストから取り残されているためです。実際に必要な要素は捨てられません。コピーはそれを行うための最も簡単な(つまり出力が最も速い)方法です。
これより長くない番号8の他の表現があります。ただし、最速のコードを使用する場合は、これが間違いなく最良のオプションです。たとえば、両方が8文字であるにもかかわらず、前者は2サイクルとしてカウントされますが、1つとしてカウントされるため、使用()()()()
は、たとえば、よりも(()()){}
高速です。一の周期を保存するためのはるかに大きな考慮に比べて無視できるQUINE:けれども、およびはるかに低いコードポイントを持っているよりも、そして、ので、それらのデータの断片を生成することははるかに高速(およびデータフラグメントがコードに少ないスペースを取るだろうとなり、も))。(…)
()
(
)
{
}
{{} … }{}{}
メインループ。これは反復をカウントしません(while
ループではなくfor
ループであり、テストを使用してブレークアウトします)。終了すると、上位2つのスタック要素を破棄します。上の要素は無害な0ですが、下の要素は「負のオフセットである」負の数である「次の反復で使用するフォーマット」であり、Mini -Flakプログラムは終了し、インタープリターはそれらを出力しようとしてクラッシュします。
このループは明示的なテストを使用してブレークアウトするため、そのテストの結果はスタックに残されるため、最初に行うこととして破棄します(値は役に立たない)。
(({})[(()()()())])
このコードは 、スタック要素fの上に4とf − 4をプッシュし、その要素をそのまま残します。次の反復の形式を事前に計算し(定数4が手元にある間)、プログラムの次のいくつかの部分でスタックを正しい順序に同時に取得します。形式としてfを使用しますこの反復、およびその前に4が必要です。
(({})( … )[{}])
これにより、f -4のコピーが作業スタックに保存され、次の反復で使用できるようになります。(その時点でもfの値は存在しますが、スタックの扱いにくい場所にあり、正しい場所に移動できたとしても、4を引くサイクルを費やさなければなりません。コードを印刷してその減算を実行します。今すぐ保存する方がはるかに簡単です。)
{{}{}((()[()]))}{}
オフセットが4であるかどうかを確認するテスト(つまり、f − 4が0)。存在する場合、データ文字列フォーマッタを印刷するため、このオフセットで1回だけではなく、データ文字列とそのフォーマッタを241回実行する必要があります。コードはかなり単純である:場合、F - 4置き換え、非ゼロであるF -零点の対と4,4自体を、どちらの場合でも、一番上のスタック要素をポップします。スタック上にf(上記の繰り返しを241回印刷したい場合)または0(一度だけ印刷したい場合)のいずれかのfを超える数字があります。
(
((((((({})){}){}{})){}{}){}){}
()
)
これは興味深い種類のBrain-Flak / Mini-Flak定数です。ここの長い行は数字の60を表して()
います。通常、Brain-Flak定数のいたるところにあるの欠如に混乱するかもしれません。これは通常の数字ではなく、数字を複製操作として解釈する教会の数字です。たとえば、ここにある60の教会の数字は、入力の60のコピーを作成し、それらをすべて1つの値に結合します。Brain-Flakでは、加算できるのは通常の数字だけです。したがって、スタックの最上部のコピーを60個追加し、スタックの最上部に60を掛けます。
補足として、Underload数字ファインダーを使用して、Underload構文で教会数字を生成し、Mini-Flakでも適切な数字を見つけることができます。アンダーロード数字(ゼロ以外)は、「最上位スタック要素の複製」:
および「最上位2つのスタック要素の結合」操作を使用し*
ます。これらの操作は両方ともBrain-Flakに存在するため、に翻訳:
し)
、*
に先頭に{}
a {}
を追加(
し、バランスをとるために開始時に十分に追加します(これはメインスタックと作業スタックの奇妙な組み合わせを使用していますが、動作します)。
この特定のコードフラグメントは、教会の数字60(実質的に「60で乗算」スニペット)を増分とともに使用して、式60 x + 1 を生成します。したがって、前のステップで4が得られた場合、 241の場合、または0があった場合は、値1を取得するだけです。つまり、必要な反復回数を正しく計算します。
241の選択は偶然ではありません。これは、a)プログラムがとにかく終了するおおよその長さ、およびb)ラウンド数の4倍を超える値になるように選択された値でした。ラウンド数(この場合は60)は、コピーする要素の柔軟性が高いため、教会の数として表現が短くなる傾向があります。プログラムには、長さを正確に最大241にするために、後でパディングが含まれます。
{
({}(
…
)[{}()])
}{}
これは、前に見たようなforループで、メインスタックの最上部と同じ回数だけコードを実行します(消費します。ループカウンター自体は作業スタックに格納されますが、これはプログラムのネストレベルに関連付けられているため、forループ自体以外の要素と対話することはできません。これは実際にデータ文字列とそのフォーマッターを1回または241回実行し、メインスタックから制御フローの計算に使用していたすべての値をポップしたので、その上で使用するフォーマットが用意されています。使用するフォーマッタ。
(␀␀!S␠su! … many more comment characters … oq␝qoqoq)
ここでのコメントは、まったく興味がないわけではありません。一つには、Brain-Flakコマンドがいくつかあります。)
終了時には、当然、プログラム作業の様々なセグメント間の遷移方法の副作用として生成されるので、(
開始時は、手動でコメント内部を入れ、それ(およびコメント内部の長さにもかかわらず、のバランスをとるために添加しました()
コマンドがまだある()
ので、すべてそれがない、コマンドの戻りデータ列の値とそのフォーマッタ、forループは完全に無視することを何か)に1を追加することです。
さらに注目すべきは、コメントの先頭にあるこれらのNUL文字は明らかに何からもオフセットされていないことです(+8と-4の違いでさえ、(
aをNUL に変えるには十分ではありません)。これらは、239要素のデータ文字列を241要素までもたらす純粋なパディングです(簡単に支払います:必要な反復回数を計算するとき、1対241ではなく1対239を生成するのに2バイト以上かかります) )。NULは可能な限り低いコードポイントを持っているため、パディング文字として使用されました(データ文字列のソースコードが短くなり、出力が速くなります)。
{}({}())
一番上のスタック要素(使用している形式)をドロップし、次に1を追加します(出力する最後の文字、つまりフォーマットしたばかりのプログラムセクションの最初の文字)。古い形式はもう必要ありません(新しい形式は作業スタックに隠れています)。ほとんどの場合、増分は無害で'
、データ文字列フォーマッタのソース表現の一方の端を(
(データ文字列自体をフォーマットするためにフォーマッタを次に実行するときにスタックで必要です)に変更します。私たちは、で開始する要素フォーマッタ各データ列を強制するので、アウトロまたはイントロでそのような変換を必要とする(
、それが多少複雑になるだろう(私たちは閉鎖する必要があるだろうと(
し、後でその効果を元に戻す)、および241個で(
はなく、ほぼ 241個のフォーマッタのコピーしか持っていないので、何らかの理由で余分なものを生成する必要があります(したがって、無害な文字'
が欠落していることが最善です)。
(({})(()()()()){})
最後に、ループ終了テスト。メインスタックの現在の最上位は、次の反復に必要な形式です(作業スタックから戻ってきたばかりです)。これによりコピーされ、コピーに8が追加されます。結果の値は、ループの次回ラウンドで破棄されます。ただし、イントロを印刷したばかりの場合、オフセットは-4であったため、「次の反復」のオフセットは-8になります。-8 + 8は0であるため、ループはその後反復に継続するのではなく終了します。