ONLY DO WHAT ONLY YOU CAN DO

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

F# で Project Euler Problem 12

Scala でのロジックをそのまま移植

> let rec get_prime_factor_list(n:int64, factor:int64) =
-     if   n          < factor * factor then  [n]
-     elif n % factor = 0L              then factor::get_prime_factor_list(n / factor, factor     )
-     else                                           get_prime_factor_list(n         , factor + 1L)
- ;;

val get_prime_factor_list : int64 * int64 -> int64 list

> get_prime_factor_list(73920L, 2L)
- ;;
val it : int64 list = [2L; 2L; 2L; 2L; 2L; 2L; 3L; 5L; 7L; 11L]
> get_prime_factor_list(28L, 2L)
- ;;
val it : int64 list = [2L; 2L; 7L]
> let mutable exp_list:List<int64> = []
- ;;

val mutable exp_list : List<int64> = []

> let mutable exp    = 0L
- ;;

val mutable exp : int64 = 0L

> let prime_factor_list = get_prime_factor_list(28L, 2L)
- ;;

val prime_factor_list : int64 list = [2L; 2L; 7L]

> let mutable factor = prime_factor_list.Head
- ;;

val mutable factor : int64 = 2L

> prime_factor_list
- |> List.iter(fun n ->
-        if n = factor then exp <- exp + 1L
-        else
-            if exp <> 0L then exp_list <- exp + 1L :: exp_list
-            factor <- n
-            exp    <- 1L
-    )
- ;;
val it : unit = ()
> exp_list <- exp + 1L :: exp_list
- ;;
val it : unit = ()
> exp_list
- ;;
val it : List<int64> = [2L; 3L]
> exp_list
- |> List.reduce(*)
- ;;
val it : int64 = 6L
> let get_factor_cnt(n:int64) =
-     let prime_factor_list = get_prime_factor_list(n, 2L)
-     let mutable exp_list:List<int64> = []
-     let mutable exp = 0L
-     let mutable factor = prime_factor_list.Head
-
-     prime_factor_list
-     |> List.iter(fun n ->
-            if n = factor then exp <- exp + 1L
-            else
-                if exp <> 0L then exp_list <- exp + 1L :: exp_list
-                factor <- n
-                exp    <- 1L
-        )
-
-     exp_list <- exp + 1L :: exp_list
-     exp_list
-     |> List.reduce(*)
- ;;

      |> List.iter(fun n ->
  -----------------^

stdin(41,18): error FS0407: The mutable variable 'exp_list' is used in an invalid way. Mutable variables cannot be captured by closures. Consider eliminating this use of mutation or using a heap-allocated mutable reference cell via 'ref' and '!'.
> let get_factor_cnt(n:int64) =
-     let prime_factor_list = get_prime_factor_list(n, 2L)
-     let exp_list = ref []
-     let exp = ref 0L
-     let factor = ref prime_factor_list.Head
-
-     prime_factor_list
-     |> List.iter(fun n ->
-            if n = !factor then exp := !exp + 1L
-            else
-                if !exp <> 0L then exp_list := !exp + 1L :: !exp_list
-                factor := n
-                exp    := 1L
-        )
-
-     exp_list := !exp + 1L :: !exp_list
-     !exp_list
-     |> List.reduce(*)
- ;;

val get_factor_cnt : int64 -> int64

> get_factor_cnt 73920L
- ;;
val it : int64 = 112L
> let mutable n = 1L
- ;;

val mutable n : int64 = 1L

> let m = 500L
- ;;

val m : int64 = 500L

> let mutable fWhile = true
- ;;

val mutable fWhile : bool = true

> while fWhile do
-     let triangular_num = n * (n + 1L) / 2L
-     let factor_cnt     = get_factor_cnt triangular_num
-
-     if factor_cnt > m then
-         printf "%d:%d->%d" n triangular_num factor_cnt
-         fWhile <- false
-     else
-         n <- n + 1L
- ;;
12375:76576500->576val it : unit = ()