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。

いろいろ