C#でProject Euler(3) LINQ

Problem 1Pythonでふつうに書くとこうなるのでした。

N = 1000
print sum(n for n in xrange(1, N) if n % 3 == 0 or n % 5 == 0)

ジェネレータ式ではなく関数で書いてみると、

print sum(ifilter(lambda n: n % 3 == 0 or n % 5 == 0, xrange(1, N)))

これに対応するC#のコードはこうなります。

using System;
using System.Linq;      // この機能を使うためのおまじない

class e001 {
    static void Main(string[] args) {
        const int   N = 1000;
        var s = Enumerable.Range(1, N - 1).
                        Where(n => n % 3 == 0 || n % 5 == 0).Sum();
        Console.WriteLine(s);
    }
}

これは、LINQという機能を使っています。一つずつ説明します。

Enumerable.Range

これは、Python2のxrangeに相当するものです。ただし、少し違います。引数は常に2つで、第2引数は生成する整数の個数です。ステップ幅は指定できず、常に一つずつインクリメントします。

Enumerable.Range(2, 3);     // 2, 3, 4

使いにくいですねえ。あとでxrange相当のメソッドを自作しましょう。

Where

関数型の関数によくあるfilterにあたるものです。なぜわざわざWhereという名前にしているかというと、SQLを意識しているんですね。ほかのメソッドもだいたいそうです。それはともかく、ここでラムダ式を引数にして、trueとなるものだけに絞り込みます。

Sum

これはそのままです。

語順

基本的に、データがまずありきで、それを加工していくという語順になっています。
一方、Pythonは数学的とも言えますが、問題文をもう一度読んでみると、

Find the sum of all the multiples of 3 or 5 below 1000.

Problem 1

この英語の語順どおりですね。たまたまという要素もありますが、英語と同じ語順の言語がネイティブの人は読みやすいかもしれません。