Perl、92 90 89 84バイト
+1を含む -n
STDINの高さを指定:
perl -M5.010 bolt.pl <<< 15
bolt.pl
:
#!/usr/bin/perl -n
map{$_=$;until$;=$_,s/.6|3.?/53|16*rand/eg,/3|6/>/36/;say y|3615|\\/ |r}(1x$_.6)x$_
説明
開始点0のオフセットを呼び出すと(ポイントは文字ボックスの隅にあります)、次の行で左または右に移動する(または移動しない)ことができ、オフセット上のポイントで終わる可能性があります-1,1
。次の行は-2,0,2
可能な限りのオフセットなどを示します。それらはすべて2 ずつ異なります。ポイントの左下の文字を偶数、右下の文字を呼び出すと、各文字位置に偶数または奇数を割り当てることができます。偶数と奇数が交互に並ぶような行(実際には、プレーン全体がチェッカーボードパターンで並べられています)。偶数ポジションには/
か
、奇数位置が持つことができます\
か
。
aの直前の文字/
は奇数の位置にあるため、\
またはのいずれか
になる可能性があります\/
が、禁止されているのでのみ
可能です。同様に、aの後の文字はaで\
なければなりません
(行の境界が問題にならないように、行の左右に十分なスペースが埋め込まれていると仮定します)。そのため、稲妻は常にaの直下\
または直下の次の行に続きます/
。いずれの場合も、下のポイントは中央にあり、次の行はこれらの4つの展開のいずれかを等しい確率で持つことができます(最初の文字をor で、2番目の文字をorで個別に置き換えることもできます)。perlでは、次のような方法でこれを行うことができます。
、/
、\
又は/\
直接トップ2文字以下です。だから私は、単にいずれかを置き換えることができ、次の行を生成します\
か、/
/
\
s#\\ | /#(" "," \\","/ ","/\\")[rand 4]#eg
ただし、結果の行に\/
(禁止された結合)が含まれている/
か\
、まったく含まれていないか、またはまったく含まれていない場合(ボルトは死に、底に到達しない)、結果は無効です。その場合、行全体を破棄して、もう一度やり直します。有効な継続は常に存在し、頻繁に試行すると、十分な継続が見つかります(たとえば、1つのフローを除いてすべてが停止します)。これは、推奨されるオーバーラップ防止アルゴリズムとはわずかに異なる確率分布ですが、方向性バイアスがないため、実際にはこれが優れていると思います。有効性は、以下を使用してゴルフっぽい方法でテストできます。
m#\\|/#>m#\\/#
ここでの問題は、ランダムな置換が非常に多く、これらの\
エスケープもすべてバイトを消費することです。だから私は、数字の文字列を使用して、私の行を構築し、して、適切な数字を変更することを決定した
、/
と\
だけ印刷前に。基本的なランダム置換は
53|16*rand
これの一つ与え53
、55
、61
または63
等しい確率を有します。それから私は解釈して5
とし1
て
、とし3
て\
そしてとし6
て/
。行の印刷について説明します。
say y|3615|\\/ |r
本格的なゴルフ大会では、代替の魔法の公式を体系的に検討し始めますが、これはかなり良いはずです(3バイト以内で最適)
プログラムの残りのコンポーネント:
1x$_.6
これ$_
により、高さのスペースに続いてが初期化されます(次のマップを参照)/
。これは、印刷される最初の行の上にある不可視の行であり、フィールドが十分に広いことを確認して、ボルトが左側のスペースを使い果たすことがないようにします
map{ ... ; say ...}(1x$_.6)x$_
この同じ初期文字列の高さを処理し、毎回新しい行を印刷します
$_=$;until$;=$_,...
現在の行をに保存します$;
。交換は、リストア無効であることが判明した場合$_
から$;
s/.6|3.?/53|16*rand/eg
実際の置換を行います。スペースである必要があるため、前/
または後を確認\
する必要はありません。スペースは1
またはで表すことができるため、これは便利5
です。文字列を左にパディングするのは、スペース\
がまだ存在しない場合もあるため、その文字をオプションにする
/3|6/>/36/
新しい行が有効かどうかを確認します
Stay safe and have fun golfing!
また、EASが攻撃された場合、すべてを放棄し、命令に従うように指定することもできます。このような状況では、ゴルフコードは優先事項ではありません。