十分に発達した fizzbuzz.bat は、魔法と区別がつかない
序
最近業務でバッチファイル読むことになったので、リハビリ兼ねてfizzbuzz書いてみた。
以前の流行りの際にも書いたものを、ちょっぴり思い出しながら(自身の書いたものならカンニングに当たらないだろう)すらすらっと書いたらそこそこ面白いものになったので晒すことにする。
@FOR /L %%n IN (1,1,100)DO @SET/AF=!(%%n%%3),B=!(%%n%%5)&CALL SET.=%%F:1=Fizz%%%%B:1=Buzz%%&CALL ECHO %%.:0=%%|FIND "z"||ECHO %%n
twitter に上げようと140バイト目標に code golf 駆使した129bytes の1行プログラム。
解説と魔術診断
@FOR /L %%n IN (1,1,100)DO
バッチの FOR /L は連番を生成できる。*nix 系の seq に相当する。
終端のかっことじの後ろの空白は任意なので、こっそり1バイト稼いでいる。
ちなみに golf 的には FOR /L よりも SET/A を使った再帰になるところ。SET/AN+=1
で済む。
@SET/AF=!(%%n%%3),B=!(%%n%%5)
剰余+否定で FizzBuzzのフラグを生成、%F%と%B%に格納する。
SET 文の /A オプションは演算時に用いるが、一度に複数の変数を弄れるので、 golf 的にはなかなか便利。
前後の空白が任意なので、こっそり2バイト稼いでいる。
&CALL SET.=%%F:1=Fizz%%%%B:1=Buzz%%
処理自体は %F% の ”1” を ”Fizz” に、%B% の ”1” を ”Buzz" に置換し、変数に格納するシンプルなもの。
それに対し、CALLを用いた遅延展開を行っている。
変数の展開時には前述の SET/A 文が判定されていないため、CALL文 + %のエスケープを用いて処理時に展開させている。
変数名「.」は英字にしないことで、SET文の後の空白を省くためのものである。
この辺りから魔術がちょっと顔を出す。
&CALL ECHO %%.:0=%%|FIND "z"||ECHO %%n
上で格納した変数の ”0” を空文字に置換して出力する。
FIND で ”z” を探して、見つかればそのまま出力、見つからない場合は数字を出力。
FINDの成功失敗で数字出力を制御するのはバッチらしくてお気に入り。
結
案外魔術っぽくなかった。変態なのは変数名だけか。