Project Eulerでれんしゅう

正月の年越しに少し挑戦してみた。

let listgen_with_filter a b step filter =
  let rec iter c l =
    if c < a then
      l
    else
      if (filter c) then
        iter (c - step) (c :: l)
      else
        iter (c - step) l
  in
    iter b []

let listgen a b step =
  let rec iter c l =
    if c < a then
      l
    else
      iter (c - step) (c :: l)
  in
    iter b []

let p1 =
  List.fold_left (+) 0
    (listgen_with_filter 1 999 1
       (fun x ->
          (x mod 3) = 0 or (x mod 5) = 0))

let p2 =
  let rec iter a b =
    let c = a + b in
      if c < 4000000 then
      c :: (iter b c)
    else
      []
  in
    List.fold_left (fun x y ->
                      if (y land 1) = 0 then
                        x + y
                      else
                        x)
      0 (1 :: 2 :: (iter 1 2))

let fib n =
  let rec iter a b i =
    let c = a + b in
      if i < n then
        c :: (iter b c (i + 1))
      else
        []
  in
    match n with
        1 -> [1]
      | 2 -> [1;2]
      | _ -> 1 :: 2 ::(iter 1 2 3)

let factorization n =
  let rec iter m c l =
    if c > m then
      l
    else if (m mod c) = 0 then
      iter (m / c) c (c :: l)
    else
      iter m (c + 1) l
  in
    iter n 2 []

let fact2 n =
  let rec iter m c l =
    if c > m then
      l
    else if (Int64.rem m c) = Int64.zero then
      iter (Int64.div m c) c (c :: l)
    else
      iter m (Int64.add c Int64.one) l
  in
    iter n (Int64.of_int 2) []

let p3 =
  match fact2 (Int64.of_string "600851475143") with
      x :: _ -> Int64.to_int x

let int2clist n =
  let rec iter i l =
    let upper = i / 10 in
    let downer = i mod 10 in
      if upper = 0 then
        downer :: l
      else
        iter upper (downer :: l)
  in
    iter n []


let int_max l =
  let rec iter l m =
    match l with
        x :: xs -> if x > m then iter xs x else iter xs m
      | [] -> m
  in
    iter l 0

let p4 =
  let l = listgen 100 999 1 in
  let lst = List.concat (List.rev_map
                           (fun x -> List.rev_map
                              (fun y -> x * y) l) l) in
    int_max (List.filter (fun n ->
                           let l = int2clist n in
                             l = (List.rev l))
               lst)