count_of_primes.sf 740 B

12345678910111213141516171819202122232425262728293031323334353637
  1. #!/usr/bin/ruby
  2. # Sublinear algorithm for counting the number of primes <= n.
  3. # Based on algorithm from:
  4. # https://math.stackexchange.com/questions/1378286/find-the-sum-of-all-primes-smaller-than-a-big-number
  5. func count_of_primes(n) {
  6. return 0 if (n <= 1)
  7. var r = n.isqrt
  8. var V = (1..r -> map {|k| idiv(n,k) })
  9. V << range(V.last-1, 1, -1).to_a...
  10. var S = Hash(V.map{|k| (k, k) }...)
  11. for p in (2..r) {
  12. S{p} > S{p-1} || next
  13. var sp = S{p-1}
  14. var p2 = p*p
  15. V.each {|v|
  16. break if (v < p2)
  17. S{v} -= (S{idiv(v,p)} - sp)
  18. }
  19. }
  20. return S{n}-1
  21. }
  22. assert_eq(
  23. 30.of { count_of_primes(_) }
  24. 30.of { .pi }
  25. )
  26. say count_of_primes(1e6) #=> 78498