http://projecteuler.net/index.php?section=problems&id=12
素因数分解すれば簡単に約数の個数を数えることができます。n+1を素因数分解して、前に求めてあるnの素因数分解とかけて2で割ります。
これ、エラーになるんですね。
let f a = a.Head printfn "%d" (f [2])
head.fs(1,11): error FS0072: Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.
引数の型を指定すれば通ります。
let f (a : int list) = a.Head printfn "%d" (f [2])
プロパティではなく関数を使えば型を指定しなくても通るんですね。
let f a = List.head a printfn "%d" (f [2])
let rec calc_exp n p = if n % p = 0 then let t = calc_exp (n / p) p (fst t + 1, snd t) else (0, n) let rec fac n p = if n = 1 then [] else if p * p > n then [(n, 1)] else let t = calc_exp n p if fst t > 0 then (p, fst t) :: (fac (snd t) (p + 1)) else fac n (p + 1) let factorize n = fac n 2 let rec mul_f f1 f2 = if List.isEmpty f1 then if List.isEmpty f2 then [] else f2 else if List.isEmpty f2 then f1 else let p1, e1 = f1.Head let p2, e2 = f2.Head if p1 = p2 then (p1, e1 + e2) :: (mul_f f1.Tail f2.Tail) else if p1 < p2 then f1.Head :: (mul_f f1.Tail f2) else f2.Head :: (mul_f f1 f2.Tail) // fは2の成分を有していること前提 let half_f (f : (int * int) list) = let e = snd f.Head if e = 1 then f.Tail else (2, e - 1) :: f.Tail let rec pow n e = if e = 0 then 1 else n * (pow n (e - 1)) let val_f f = List.fold (fun x y -> x * (pow (fst y) (snd y))) 1 f let s = seq { let prev_fac = ref [] for n in Seq.initInfinite(fun i -> i + 1) do let f = factorize(n + 1) let f2 = half_f (mul_f !prev_fac f) yield (val_f f2, List.fold (fun x y -> (x * ((snd y) + 1))) 1 f2) prev_fac := f } let N = 500 printfn "%A" (fst (Seq.head (Seq.filter (fun x -> snd(x) > N) s)))