鳳鳴は祖父の俳号

日記 メモ そんなの

gforthでfizzbuzz 4年ぶりの改善

 twitterで@nfunatoさんからメンション。anarchy golfというプログラムの記述量をいかに少なくするかを競うゲームで、fizzbuzzをforthで書くやつについて。

私が以前投稿してたコードはこれ。

: m mod 0= ; : z 1 DO i 5 m i 3 m 2dup or 0= if i 1 .r then if ." Fizz" then if ." Buzz" then cr LOOP ; 101 z

1 .r の所は単に . でいいんじゃないのの指摘を受けた。当時なぜそう書いたのか思い出せない。修正すると

: m mod 0= ; : z 1 DO i 5 m i 3 m 2dup or 0= if i . then if ." Fizz" then if ." Buzz" then cr LOOP ; 101 z

これで3文字分減った。

@nfunatoさんの最初のコードは
FizzBuzz in gforth (for code golf) · GitHub

: t mod 0= if type 0 then ;
: x 101 1 do s" Fizz" i 3 t s" Buzz" i 5 t nip and if i . then cr loop ;
x

改善されたコードは
FizzBuzz in gforth (for code golf) · GitHub

: x 101 1 do 1 i 3 mod 0= if ." Fizz" 1- then i 5 mod if if i . then else ." Buzz" then cr loop ; x

これで99文字とのこと。

ちょっと解説。
: m mod 0= ; はワードの定義。 以降 m だけで mod 0= と同じ。毎回書くと長くなってしまうのでこうしている。
do ... loop はワードの定義内でしか使えない。if else then も同様でプログラムの流れを制御するものは直接使えない。do ... loop の中でiは特別な名前で、ループ変数を表す。
." は文字列を表示。forthのワード区切りはスペースなので ." Fizz" はダブルクオーテーションにくくられた文字列、ではなく続く文字列の最後が"で終わるまでを出力。

 code golf初めてやった頃は速度優先だろ記述はどうでもいいんだと思ってたけど、コード量削減のためにパズルの様に考えると色々調べるので結果的に詳しくなれるのであった。