読者です 読者をやめる 読者になる 読者になる

kubo39's blog

ただの雑記です。

D言語のfizzbuzz

FizzBuzzD言語っぽいコードってどんな感じだろう、みたいな話があったので。

ふつうに実行時に書くならこんな感じだろうか。

import std.algorithm;
import std.conv : to;
import std.range;
import std.stdio;

void main()
{
    1.iota(16)
        .map!(a => (! (a % 15)) ? "fizzbuzz" : (! (a % 5)) ? "buzz" : (! (a % 3)) ? "fizz" : a.to!string )
        .each!writeln;
}

コンパイルfizzbuzzの愚直な例。 dmd -c fizzbuzz.d で動かせばコンパイル時出力確認できる。

string fizzbuzz(alias n)()
{
    import std.conv : to;
    static if (!(n % 15)) return "fizzbuzz";
    static if (!(n % 3)) return "fizz";
    static if (!(n % 5)) return "buzz";
    else return n.to!string;
}

pragma(msg, fizzbuzz!1);
pragma(msg, fizzbuzz!2);
pragma(msg, fizzbuzz!3);
pragma(msg, fizzbuzz!4);
pragma(msg, fizzbuzz!5);
pragma(msg, fizzbuzz!6);
pragma(msg, fizzbuzz!7);
pragma(msg, fizzbuzz!8);
pragma(msg, fizzbuzz!9);
pragma(msg, fizzbuzz!10);
pragma(msg, fizzbuzz!11);
pragma(msg, fizzbuzz!12);
pragma(msg, fizzbuzz!13);
pragma(msg, fizzbuzz!14);
pragma(msg, fizzbuzz!15);

再帰で書くのは逆順しか思いつかなかった。

auto fizzbuzz(alias n)()
{
    import std.conv : to;
    static if (n == 1) {
        return 1;
    } else {
        pragma(msg, (! (n % 15)) ? "fizzbuzz" : (! (n % 5)) ? "buzz" : (! (n % 3)) ? "fizz" : n.to!string );
        return fizzbuzz!(n - 1);
    }
}

pragma(msg, fizzbuzz!15);