網膜、12バイト
バイトカウントはISO 8859-1エンコードを前提としています。
+%`\B
¶$`:
1
オンラインでお試しください!
代替ソリューション:
+1`\B
:$`:
1
説明
これはおそらく、ゴルフの少ない古いバージョンに基づいて説明し、それを短縮した方法を示すのがおそらく簡単です。次のようにバイナリを10進数に変換していました。
^
,
+`,(.)
$`$1,
1
Retinaで10進数を構築する唯一の賢明な方法は、物事を数えることです(Retinaには、金額を表す10進数を出力できる機能がいくつかあるため)。したがって、実際に唯一可能なアプローチは、バイナリを単項に変換し、単項の桁数をカウントすることです。最後の行はカウントを行うため、最初の4行はバイナリを単項に変換します。
どうすればいいですか?一般に、ビットのリストから整数に変換するには、結果を次のように初期化します。0
からビットを最上位から最下位まで調べ、既存の値を2倍にして現在のビットを追加します。たとえば、2進数がの場合、1011
実際に計算します:
(((0 * 2 + 1) * 2 + 0) * 2 + 1) * 2 + 1 = 11
^ ^ ^ ^
明確にするために個々のビットにマークを付けました。
単項でこれを行うためのトリックは、a)倍にすることは単に数を繰り返すことを意味し、b)カウントしているので 1
最後にsをているため、プロセスで0
sと1
s を区別する必要さえありません。これはすぐに明らかになります。
プログラムが行うことは、最初にカンマをマーカーとして最初に追加し、すでに処理した入力の量を示すことです。
^
,
マーカーの左側には、累積する値(ゼロの単項表現に正しく初期化されます)があり、値の右側は処理する次のビットになります。次に、ループ内で次の置換を適用します。
,(.)
$`$1,
とを見るだけで,(.)
、$1,
毎回マーカーが1ビット右に移動します。ただし$`
、マーカーの前にあるすべて、つまり現在の値を挿入して、2倍にします。inputを処理する際の個々のステップを以下に示します。各行の上1011
に挿入した結果をマークしました$`
(最初のステップでは空です)。
,1011
1,011
_
110,11
___
1101101,1
_______
110110111011011,
ゼロを保持し、他のすべてと一緒にゼロを2倍にしたことがわかりますが、最後にそれらを無視しているので、1
s の数が2正しい。あなたがそれらを数えるなら11
、私たちが必要なものだけがあります。
そのため、これをゴルフする方法の問題は12バイトまで残されます。18バイトバージョンの最も高価な部分は、マーカーを使用する必要があることです。目標はそれを取り除くことです。すべてのビットのプレフィックスを2倍にしたいので、最初のアイデアは次のようになります。
.
$`$&
問題は、これらの置換が同時に発生するため、最初のビットがビットごとに2倍になるのではなく、毎回1回だけコピーされることです。入力1011
については、挿入されたマークを付け$`
ます:
_ __ ___
1101011011
入力を再帰的に処理して、2番目のプレフィックスが2番目のプレフィックスで再び2倍になるようにする必要があります。1つのアイデアは、どこにでもマーカーを挿入し、プレフィックスを繰り返し置換することです。
\B
,
+%`,
¶$`
各マーカーを最初にプレフィックスで置き換えた後、入力の開始位置を覚えておく必要があります。そのため、ラインフィードも挿入し、%
オプションを使用して、次の$`
ものが最も近いラインフィードのみを拾うようにします。
これは機能しますが、それでも長すぎます(1
最後にsをカウントするときは16バイト)。物事を好転させるのはどうですか?マーカーを挿入する場所は\B
(2桁の間の位置)で識別されます。なぜそれらの位置にプレフィックスを挿入しないのですか?これはほとんど機能しますが、違いは、以前のソリューションでは、各置換で実際に1つのマーカーを削除したことです。これは、プロセスを終了させるために重要です。ただし、\B
文字ではなく位置だけなので、何も削除されません。私たちはすることができますしかし、停止します\B
代わりに、この場所に数字以外の文字を挿入することにより、マッチングから。これにより、非単語境界が単語境界に変わります。これは、マーカー文字を以前に削除するのと同じです。そして、それが12バイトのソリューションの機能です。
+%`\B
¶$`:
完全を期すために、ここに処理の個々のステップを示します1011
。各ステップの後に空の行があります。
1
1:0
10:1
101:1
1
1:0
1
1:0:1
1
1:0
10:1:1
1
1:0
1
1:0:1
1
1:0
1
1:0:1:1
繰り返しますが、最後の結果には正確に11が含まれていることがわかります1
。
読者のための演習として、これが他のベースに非常に簡単に一般化する方法を見ることができます(ベースの増分ごとに数バイト追加します)。