D言語のUFCSを使い倒す
こんにちは。 今回は、dmdに最近実装された機能であるUFCSを使って、AOJの簡単な問題をなるべくセミコロンを打たずに解いていきます。
簡単な問題ということで、Volume 0の0000番を選びました。
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0000&lang=jp
import std.stdio, std.range, std.algorithm, std.conv;
void main()
{
1.iota(10).map!(a => 1.iota(10).map!(b => a.to!string() ~ "x" ~ b.to!string() ~ "=" ~ (a * b).to!string())().join("\n"))().join("\n").writeln();
}
D言語だと、セミコロンを2つしか打たずに、かつとても簡単にかけますね。 コードの中身を簡単に解説していきます。
上のコードは、iotaでまずRangeを2つ作り、それをto!stringで変換しつつうまく組み合わせて文字列を作っています。 そして、joinで改行をはさみつつ結果になる文字列を生成し、それをwritelnしています。
iotaは上記のようにまっとうな方法で使うこともできますが、まっとうじゃない方法で使うこともできます。
import std.stdio, std.range, std.algorithm;
void main()
{
100.iota().map!(a => ("Hello, world!".writeln(), 0)).array();
}
上のコードは、Hello, world!と百行ほど出力するコードです。 100.iota()とやると、ちょうど要素の数が100のRangeが出来上がります。 それを利用して、そのRangeをmapして、mapの述語内で副作用のある操作をすると、 for文とおよそ同等のことができます。 最後にarrayでRangeを配列に変換している理由は、Rangeが遅延評価であるためです。
D言語だと、上のようにセミコロンを全く打たずにコードが書けて楽しいですね。