shaitan's blog

長文書きたいときに使う.

TeXっぽいことを書けと言われたが

最近はTeX*1を触っていないのでネタがないのだが、書くと喜ぶ人がいるようなので昔twitterでつぶやいたネタの解説をする。

FizzBuzz問題。140文字以内にするのに苦労した記憶がある。

ちゃんとTeXで書いてある*2ので、適当なファイル(fizzbuzz.texとでもしよう)に保存して、tex fizzbuzz.texすれば、*が出てきて止まるので、\endと入れるとfizzbuzz.dviを出力してくれるはずである。いちいち入れるのが面倒な場合は末尾に\endを付けて保存しておけば大丈夫。*3

適宜分けて書く。

\let~\ifnum\let\c\newcount\let\a\advance

ここは文字数を削減するため、繰り返し出てくるコントロールシーケンスを短いものに割り当てている。
~はアクティブ文字(カテゴリーコード13)なので1文字で命令となる。\aや\cもあまり考えず名前を付けているので、何らかの文書に埋め込んで使うといった用途の場合、このあたりは修正した方が良いだろう。

\c\f\c\b\c\n

カウンタ\f,\b,\nを宣言(?)。0で初期化される。それぞれ、Fizz用、Buzz用、数字用のカウンタ。
なお、これらも衝突の危険があるため注意。

\loop~\n<100 ... \repeat

カウンタ\nを99まで回すループ。

\a\f1\a\b1\a\n1

カウンタ\f,\b,\nを1加算する。

~\f=3\f0Fizz\fi

\fが3になったら\fを0にしてFizzを出力。

~\b=5\b0Buzz\else~\f>0{\the\n}\fi\fi\ 

\bが5になったら\bを0にしてBuzzを出力し、
\bが5でないときに、\fが0でない(FizzもBuzzも出力されていない)ときには\nの値を出力。

\ 

それぞれの数に対応する出力の間の区切りのスペース。これだと最後に無駄なスペースが入ってしまうので改良の余地がある。

*1:ここではオリジナルのエンジンではなく、それに関連するもの全体を指している。多くの人がTeXと呼んでいるそれだと思っていただければよい。

*2:ここではLaTeXなどで定義された命令を使ってない、程度の意味

*3:実はオリジナルのtexエンジン使ったの初めてかもしれない。よく分からなかったのでTeXBookの6章を参照した。