http://projecteuler.net/index.php?section=problems&id=38
nで左辺第1項の範囲が決まるので、あとはpandigitalになっているかチェックするだけ。
let rec pow n e = if e = 0 then 1 else n * (pow n (e - 1)) let rec digits n = if n = 0 then [] else (digits (n / 10)) @ [n % 10] let to_number a = List.fold (fun x y -> x * 10 + y) 0 a let rec is_pandigital ds flag = if ds = [] then true else let d = List.head ds if d = 0 then false else let f = 1 <<< d if (flag &&& f) = 0 then is_pandigital (List.tail ds) (flag ||| f) else false let ceil n m = (n + m - 1) / m let seq_pali n = seq { let q = 9 / n let r = 9 % n let min_m = if r > 0 then ceil (pow 10 q) (n - r + 1) else pow 10 (q - 1) let max_m = if r > 0 then ((pow 10 (q + 1)) - 1) / (n - r) else ((pow 10 q) - 1) / n for m in min_m..max_m do let a = List.concat (seq { for k in 1..n -> digits (k * m) }) if is_pandigital a 0 then yield (to_number a) } printfn "%d" (Seq.max (seq { for n in 2..9 do for m in seq_pali n -> m }))