さて、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で返す必要はありません。値をメソッドの最後に書けばよいです。
ついでですが、式にセミコロンは必要ありません。