smarandache_function.jl 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/julia
  2. # Trizen
  3. # 17 September 2016
  4. # https://github.com/trizen
  5. # A decently efficient algorithm for computing the results of the Kempner/Smarandache function.
  6. # See also: https://projecteuler.net/problem=549
  7. # https://en.wikipedia.org/wiki/Kempner_function
  8. # https://mathworld.wolfram.com/SmarandacheFunction.html
  9. # ∑S(i) for 2 ≤ i ≤ 10^2 == 2012
  10. # ∑S(i) for 2 ≤ i ≤ 10^6 == 64938007616
  11. # ∑S(i) for 2 ≤ i ≤ 10^8 == 476001479068717
  12. using Primes
  13. function smarandache(n::Int64, cache)
  14. isprime(n) && return n
  15. f = factor(n)
  16. count = 0
  17. distinct = true
  18. for v in values(f)
  19. count += v
  20. if (distinct && v != 1)
  21. distinct = false
  22. end
  23. end
  24. distinct && return maximum(keys(f))
  25. if (length(f) == 1)
  26. k = collect(keys(f))[1]
  27. (count <= k) && return k*count
  28. if haskey(cache, n)
  29. return cache[n]
  30. end
  31. max = k*count
  32. ff = factorial(BigInt(max - k))
  33. while (ff % n == 0)
  34. max -= k
  35. ff /= max
  36. end
  37. cache[n] = max
  38. return max
  39. end
  40. arr = Int64[]
  41. for (k,v) in f
  42. push!(arr, v == 1 ? k : smarandache(k^v, cache))
  43. end
  44. maximum(arr)
  45. end
  46. #
  47. ## Tests
  48. #
  49. function test()
  50. cache = Dict{Int64, Int64}()
  51. limit = 10^2
  52. sumS = 0
  53. for k in 2:limit
  54. sumS += smarandache(k, cache)
  55. end
  56. println("∑S(i) for 2 ≤ i ≤ $limit == $sumS")
  57. if (limit == 100 && sumS != 2012)
  58. warn("However that is incorrect! (expected: 2012)")
  59. end
  60. end
  61. test()