ONLY DO WHAT ONLY YOU CAN DO

こけたら立ちなはれ 立ったら歩きなはれ

F# で Project Euler Problem 1

3か5の倍数になっている1000未満の自然数を足し合わせよ

10未満の自然数のうち, 3 もしくは 5 の倍数になっているものは 3, 5, 6, 9 の4つがあり, これらの合計は 23 になる.

同じようにして, 1000 未満の 3 か 5 の倍数になっている数字の合計を求めよ.

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

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

F#

単純に加算
> [1..9];;
val it : int list = [1; 2; 3; 4; 5; 6; 7; 8; 9]
> [1..9]
- |> List.filter (fun x -> x % 3 = 0 || x % 5 = 0)
- ;;
val it : int list = [3; 5; 6; 9]
> [1..9]
- |> List.filter (fun x -> x % 3 = 0 || x % 5 = 0)
- |> List.sum
- ;;
val it : int = 23
> [1..999]
- |> List.filter (fun x -> x % 3 = 0 || x % 5 = 0)
- |> List.sum
- ;;
val it : int = 233168
>
等差数列の和
> let sn a lim =
-   let n = lim / a in
-   let l = a * n in
-   (a + l) * n / 2
- ;;

val sn : int -> int -> int

> sn 3 9;;
val it : int = 18
> [3;5]
- |> List.map (fun n -> sn n 999)
- |> List.sum
- |> fun x -> x - sn 15 999
- ;;
val it : int = 233168
>

ちょっと、中途半端...
List [3;5;15] に対しての処理にしたいところ

> [3;5;15]
- |> List.map (fun n -> if n = 15 then -(sn n 999) else sn n 999)
- |> List.sum
- ;;
val it : int = 233168
>

こんなもんか

> let multiples_of_3_and_5 n =
-     if   n = 15 then -(sn n 999)
-     else               sn n 999
- ;;

val multiples_of_3_and_5 : int -> int

> [3;5;15]
- |> List.map (fun n -> multiples_of_3_and_5 n)
- |> List.sum
- ;;
val it : int = 233168
> [3;5;15]
- |> List.map multiples_of_3_and_5
- |> List.sum
- ;;
val it : int = 233168
>

等差数列の和

初項a、公差d の等差数列の初項から第n項 (末項 l=a+(n−1)d) までの和Snは