838 Not coprime.sf 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. #!/usr/bin/ruby
  2. # Not coprime
  3. # https://projecteuler.net/problem=838
  4. # Let f(N) be the smallest positive integer that is not coprime to any positive integer n <= N
  5. # whose least significant digit is 3.
  6. # For example f(40) equals to 897 = 3 ⋅ 13 ⋅ 23 since it is not coprime to any of 3, 13, 23, 33.
  7. # By taking the natural logarithm (log to base ) we obtain ln f(40) = ln 897 ≈ 6.799056
  8. # when rounded to six digits after the decimal point.
  9. # You are also given ln f(2800) ≈ 715.019337.
  10. # Runtime: 7.351s
  11. # [2183, 2773]
  12. # [945433, 954803, 955523, 964993, 973543, 975703, 982913, 983933, 985373, 985793, 993403, 995563]
  13. func f(n) {
  14. var arr = (1..n -> grep{ _%10 == 3})
  15. var primes = arr.grep{.is_prime}
  16. var prime_prod = primes.prod
  17. var t = prime_prod
  18. var coprime = arr.grep{ .is_coprime(t) }
  19. #say coprime.group_by{.gpf}
  20. #say coprime.group_by{.lpf}
  21. var lpfs = Set(coprime.map{.lpf}.uniq.sort...)
  22. var w = (coprime - coprime.grep { !lpfs.has(.gpf) })
  23. lpfs = Set(w.map{.lpf}.uniq.sort...)
  24. t = lcm(t, lpfs.to_a.lcm)
  25. t = lcm(arr.grep{ .is_coprime(t) }.map{.gpf}.lcm, t)
  26. return t
  27. }
  28. say f(40)
  29. say f(2800).log.round(-6)
  30. say f(1e6).log.round(-6)
  31. __END__
  32. 250622.192757