ScalaでProject Euler(2)

さて、Problem 1から解いていきましょうか。

Problem 1

この問題の最も簡単な解き方は、オイラー図を描くことです。オイラー図はここではベン図と同じようです。すなわち、3の倍数の和と5の倍数の和を足して、そこから重なる部分の15の倍数の和を引くことです。コードを見ていきましょう。

def sum_multiple(m :Int, N :Int) = {
    val n = (N - 1) / m
    m * n * (n + 1) / 2
}

val N = 1000
println (sum_multiple(3, N) + sum_multiple(5, N) - sum_multiple(15, N))

メソッド

defで始まる定義は、関数ではなくメソッドだそうです。言語学者ではないのでどちらでもいいんですが。戻り値の型は多くの場合型推論が働くため省略できるのですが、引数の型は省略できないそうです。Haskellなら型推論が働いて省略できるのに。

sum_multiple m n = m * q * (q + 1) `div` 2
                    where q = div (n - 1) m

n = 1000
main = print ((sum_multiple 3 n) + (sum_multiple 5 n) - (sum_multiple 15 n))

ちなみに、関数の定義は次のようにします。

val sum_multiple = (m :Int, N :Int) => {
    val q = (N - 1) / m
    m * q * (q + 1) / 2
}

変数の宣言

    val n = (N - 1) / m

のvalは変数の宣言です。valで宣言すると値を変更することはできません。すなわち定数です。変更したい場合はvarで宣言します。valとvarが見分けにくいという批判も見かけますが、varはどうしてもという場合以外には使わないようにしたいものです。ですから、見分けにくくても問題ありません。

戻り値

戻り値はreturnで返す必要はありません。値をメソッドの最後に書けばよいです。
ついでですが、式にセミコロンは必要ありません。