/Euler/FSharpSolutions/Problem21.fs

https://github.com/bretambrose/EulerPublic · F# · 68 lines · 27 code · 9 blank · 32 comment · 7 complexity · 67a577907612475ba31ac69df6c4c86a MD5 · raw file

  1. (*
  2. Problem21.fs
  3. Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n).
  4. If d(a) = b and d(b) = a, where a != b, then a and b are an amicable pair and each of a and b are called amicable numbers.
  5. For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2, 4, 71 and 142; so d(284) = 220.
  6. Evaluate the sum of all the amicable numbers under 10000.
  7. Solution Notes:
  8. I should get rid of both n and divisor_sum_array from the tail aux function by making it local and setting n to the array length
  9. One potential gotcha, you must check to see if a number refers to itself as the problem definition requires the pair of numbers to be different from one another. There are
  10. several numbers (perfect) which fall into this category.
  11. (c) Copyright 2011, Bret Ambrose (mailto:bretambrose@gmail.com).
  12. This program is free software: you can redistribute it and/or modify
  13. it under the terms of the GNU General Public License as published by
  14. the Free Software Foundation, either version 3 of the License, or
  15. (at your option) any later version.
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. GNU General Public License for more details.
  20. You should have received a copy of the GNU General Public License
  21. along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. *)
  23. module Problem21
  24. open System
  25. let rec Amicable_Sum_Tail_Aux ( divisor_sum_array : int [] ) n current_number current_sum =
  26. if current_number >= n then
  27. current_sum
  28. else
  29. let current_divisor_sum = divisor_sum_array.[ current_number ]
  30. if current_divisor_sum < 2 || current_divisor_sum >= n || current_divisor_sum = current_number || divisor_sum_array.[ current_divisor_sum ] <> current_number then
  31. Amicable_Sum_Tail_Aux divisor_sum_array n ( current_number + 1 ) current_sum
  32. else
  33. Amicable_Sum_Tail_Aux divisor_sum_array n ( current_number + 1 ) ( current_sum + current_number );;
  34. let Amicable_Sum_Tail divisor_sum_array n =
  35. Amicable_Sum_Tail_Aux divisor_sum_array n 2 0;;
  36. let Problem21_v1 n =
  37. let divisor_sum_array = Array.init n (fun x -> 0)
  38. for current_number = 0 to n - 1 do
  39. divisor_sum_array.[ current_number ] <- UserNumerics.Divisor_Sum current_number
  40. Amicable_Sum_Tail divisor_sum_array n;;
  41. let Problem21_v1_Interactive() =
  42. printfn "Problem 21: Evaluate the sum of all the amicable numbers under N, where N = 10000."
  43. printfn "Input alternate N:"
  44. let N_string = Console.ReadLine()
  45. let success, N = Int32.TryParse N_string
  46. if success = true then
  47. let result_N = Problem21_v1 N
  48. printfn "For N = %d, the answer is %d" N result_N
  49. ();;