alternative D
D言語のズンドコキヨシは既にありますが、ここでは再帰を用いた実装をしてみましょう。
DMDだと最適化オプションを付ける事で末尾再帰の最適化が行われます。
kiyoshi
import std.stdio, std.random, std.algorithm;
enum zzzzd = "ズンズンズンズンドコ";
string zundoko(string zunzun)
{
return zunzun.endsWith(zzzzd) ?
zunzun ~ "キ・ヨ・シ!"
:
zundoko(zunzun ~ (dice(1,1) == 0 ? "ズン" : "ドコ"));
}
string zundoko()
{
return zundoko("");
}
void main()
{
zundoko().writeln;
}
どこかで書いたようなコードですね。これだと面白くありません。
なので、もっとD言語らしいコードにしてみましょうか。
D言語らしいコード……そう、CTFEですね!
kiyoctfe
import std.stdio, std.random, std.algorithm;
template kiyoctfe()
{
enum zzzzd = "ズンズンズンズンドコ";
string zundoko()
{
auto rnd = Xorshift(0U.reduce!"a*9+b"(__DATE__ ~ __TIME__));
string impl(string zunzun)
{
return zunzun.endsWith(zzzzd) ?
zunzun ~ "キ・ヨ・シ!"
:
impl(zunzun ~ (uniform(0, 2, rnd) ? "ズン" : "ドコ"));
}
return impl("");
}
enum kiyoctfe = zundoko();
}
void main()
{
writeln(kiyoctfe!());
}
コンパイル時に全ての計算を終わらせているので極めて高速です。
ただし、コンパイル時に結果が決まってしまうので、同じ実行ファイルを何度実行しても同じズンドコしか表示されないという欠点はありますが、しかし実行するまでは答えが分からないので問題ありません。むしろ実行して観測した時点で答えが収束すると考えれば毎回違う答えが出てくるよりも「正しい」実装だとは言えないでしょうか? 言えませんか……。
おまけ
noMain
...(略)...
/++
void main()
{
writeln(kiyoctfe!());
}
++/
pragma(msg, kiyoctfe!());
これで% dmd -O kiyoctfe.d -main
とかやれば問題解決ですね。