FizzBuzz問題をC++とFIFOLでやる
ただいまはてな界隈でFizzBuzz問題が流行中。
1から100までの数をプリントするプログラムを書け。ただし3の倍数のときは数の代わりに「Fizz」と、5の倍数のときは「Buzz」とプリントし、3と5両方の倍数の場合には「FizzBuzz」とプリントすること。
はてブのコメントがすごいことになってる。
C++
とりあえずC++で実装してみた。(後日、剰余無し+ワンライナー)
#include <iostream> using std::cout; using std::endl; void fizzbuzz() { for (int i = 1; i <= 100; i++) { if (!(i%3)) { cout << "Fizz"; } if (!(i%5)) { cout << "Buzz"; } if (i%5 && i%3) { cout << i; } cout << endl; } }
2分では書けなかった。早く書こうと思うと、名前空間使用の宣言などの呪文が邪魔なのだ。あと、横着して括弧を外そうとして、%と!の演算子の優先順位でしばらく考えた。はじめから括弧でくくっていれば2分かからなかったと思う。
思いっきり手続き依存になっているが、15は3と5の公倍数なので
if (!(i%15)) { cout << "FizzBuzz"; }
は入れない。
最適化はいろんな人がやっているのでとりあえず放置。
FIFOL
メジャーな言語での実装ははてな界隈他、多くの人がやっているので、FIFOLで書いてみた。
{ 1 add dup 15 rot mod 0 rot eq { newfifo -1 -2 rot fifopush rot rot fifopush rot = } { dup 3 rot mod 0 rot eq { newfifo -1 rot fifopush rot = } rot if dup 5 rot mod 0 rot eq { newfifo -2 rot fifopush rot = } rot if } rot ifelse dup 3 rot mod 0 rot eq dup 5 rot rot mod 0 rot rot eq rot rot or rot not { dup = } rot if dup 100 rot eq { exit } rot if } 0 loop
FIFOLには文字列リテラルがないので、
Fizz ... [ -1 ] Buzz ... [ -2 ] FizzBuzz ... [ -1 -2 ]
としておいた。"FizzBuzz"が
[ -1 ][ -2 ]
でなく
[ -1 -2 ]
なのは、FIFOLはオブジェクトをひとつ出力すると強制的に改行が入るため。それゆえ、上述のC++版では入れなかったmod15の演算が入り、その判定と分岐も入ることに。
書くのに20分くらいかかった。ひさしぶりにFIFOLでプログラム書いたけど、改めてFIFOLの生産性の低さにorz。
いろいろ
- 竹迫さん perl, x86
- C++で剰余無し+ワンライナー