ONLY DO WHAT ONLY YOU CAN DO

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

F# で Project Euler Problem 21

> let mutable map:Map<int, int> = Map.empty;;

val mutable map : Map<int,int> = map []

> let rec get_prime_factor (map:Map<int, int> byref) (n:int) (factor: int) =
-     if n  >= factor then
-         if n % factor <> 0 then
-             get_prime_factor &map n (factor + 1)
-         else
-             if Map.containsKey factor map then
-                 let n = map.[factor] + 1
-                 map <- map.Remove factor
-                 map <- (map |> Map.add factor n)
-             else
-                 map <- (map |> Map.add factor 1)
-
-             get_prime_factor &map (n / factor) factor
- ;;

val get_prime_factor : byref<Map<int,int>> -> int -> int -> unit

> get_prime_factor &map 28 2;;
val it : unit = ()
> map
- ;;
val it : Map<int,int> = map [(2, 2); (7, 1)]
> map
- |> Map.iter (fun k t -> printf "%d -> %d\n" k t)
- ;;
2 -> 2
7 -> 1
val it : unit = ()
> map
- |> Map.map (fun k t -> System.Math.Pow(float k,float t))
- ;;
val it : Map<int,float> = map [(2, 4.0); (7, 7.0)]
> map
- |> Map.map (fun k t -> System.Math.Pow(float k,(float t) + 1.0))
- ;;
val it : Map<int,float> = map [(2, 8.0); (7, 49.0)]
> map
- |> Map.map (fun k t -> System.Math.Pow(float k,(float t) + 1.0) - 1.0)
- ;;
val it : Map<int,float> = map [(2, 7.0); (7, 48.0)]
> map
- |> Map.map (fun k t -> (System.Math.Pow(float k,(float t) + 1.0) - 1.0) / float (k - 1))
- ;;
val it : Map<int,float> = map [(2, 7.0); (7, 8.0)]
> map
- |> Map.map (fun k t -> (System.Math.Pow(float k,(float t) + 1.0) - 1.0) / float (k - 1))
- |> Map.toList
- ;;
val it : (int * float) list = [(2, 7.0); (7, 8.0)]
> map
- |> Map.map (fun k t -> (System.Math.Pow(float k,(float t) + 1.0) - 1.0) / float (k - 1))
- |> Map.toList
- |> List.map (fun (k, t) -> t)
- ;;
val it : float list = [7.0; 8.0]
> map
- |> Map.map (fun k t -> (System.Math.Pow(float k,(float t) + 1.0) - 1.0) / float (k - 1))
- |> Map.toList
- |> List.map (fun (k, t) -> t)
- |> List.reduce(*)
- ;;
val it : float = 56.0
> int (map
- |> Map.map (fun k t -> (System.Math.Pow(float k,(float t) + 1.0) - 1.0) / float (k - 1))
- |> Map.toList
- |> List.map (fun (k, t) -> t)
- |> List.reduce(*))
- ;;
val it : int = 56
> let sum_of_proper_divisors (n:int):int =
-     let mutable map:Map<int, int> = Map.empty
-     get_prime_factor &map n 2
-
-     if map.IsEmpty then 0
-     else
-         int (map
-         |> Map.map (fun k t -> (System.Math.Pow(float k,(float t) + 1.0) - 1.0) / float (k - 1))
-         |> Map.toList
-         |> List.map (fun (k, t) -> t)
-         |> List.reduce(*)) - n
- ;;

val sum_of_proper_divisors : int -> int
> sum_of_proper_divisors 220;;
val it : int = 284
> sum_of_proper_divisors 284;;
val it : int = 220
>
- let mutable ami_list:List<int> = [];;

val mutable ami_list : List<int> = []

> for i in [1 .. 10000] do
-     let n = sum_of_proper_divisors i
-     if i <> n then
-         let m = sum_of_proper_divisors n
-         if i = m then ami_list <- n::ami_list
- ;;
val it : unit = ()
> ami_list
- ;;
val it : List<int> =
  [6232; 6368; 5020; 5564; 2620; 2924; 1184; 1210; 220; 284]
> ami_list
- |> List.reduce(+)
- ;;
val it : int = 31626