fork download
  1. #!/usr/bin/ruby
  2.  
  3. def primes(upto, &block)
  4. return large_primes(upto, &block) if upto > 25000
  5. upto -= 1
  6. flags = Array.new(upto, true)
  7. (0...upto-1).each do |i|
  8. if flags[i] then
  9. prime = i + 2
  10. k = i + prime
  11. while k < upto do
  12. flags[k] = false
  13. k += prime
  14. end
  15. block.call(prime)
  16. end
  17. end
  18. end
  19.  
  20. def large_primes(upto, &block)
  21. # The Algorithm is adapted from http://w...content-available-to-author-only...k.com/~jrm/printprimes.html
  22. # This code is a translated version of Andreas Raab's #largePrimesUpTo:do: method
  23. # which was written for the Squeak Smalltalk environment.
  24.  
  25. idx_limit = Math.sqrt(upto) + 1
  26.  
  27. flags = Array.new((upto + 2309) / 2310 * 60 + 60, 0xFF)
  28. # flags = "\377" * ((upto + 2309) / 2310 * 60 + 60)
  29.  
  30. primes_up_to_2310 = []
  31. primes(2310) {|prime| primes_up_to_2310 << prime}
  32.  
  33. mask_bit_idx = Array.new(2310)
  34. bit_idx = -1
  35. mask_bit_idx[0] = (bit_idx += 1)
  36. mask_bit_idx[1] = (bit_idx += 1)
  37.  
  38. (0..4).each {|i| block.call(primes_up_to_2310[i])}
  39.  
  40. idx = 5
  41. (2..2309).each do |n|
  42. while primes_up_to_2310[idx] < n do idx += 1 end
  43. if n == primes_up_to_2310[idx] then
  44. mask_bit_idx[n] = (bit_idx += 1)
  45. elsif n % 2 == 0 || n % 3 == 0 || n % 5 == 0 || n % 7 == 0 || n % 11 == 0 then
  46. mask_bit_idx[n] = 0
  47. else
  48. mask_bit_idx[n] = (bit_idx += 1)
  49. end
  50. end
  51.  
  52. (13..upto).step(2) do |n|
  53. if (mask_bit = mask_bit_idx[n % 2310]) != 0 then
  54. byte_idx = n / 2310 * 60 + (mask_bit-1 << -3)
  55. bit_idx = 1 << (mask_bit & 7)
  56. if flags[byte_idx] & bit_idx != 0 then
  57. block.call(n)
  58. if n < idx_limit then
  59. idx = n * n
  60. if (idx & 1) == 0 then idx += n end
  61. while idx <= upto do
  62. if (mask_bit = mask_bit_idx[idx % 2310]) != 0 then
  63. byte_idx = idx / 2310 * 60 + (mask_bit-1 << -3)
  64. mask_bit = 255 - (1 << (mask_bit & 7))
  65. flags[byte_idx] = flags[byte_idx] & mask_bit
  66. end
  67. idx += 2 * n
  68. end
  69. end
  70. end
  71. end
  72. end
  73. end
  74.  
  75. max = ARGV.size == 1 ? ARGV[0].to_i : 100
  76. c = 0
  77. q = 0
  78. primes(max) {|prime| q = prime; c += 1}
  79. puts q, c
Success #stdin #stdout 0s 4832KB
stdin
Standard input is empty
stdout
97
25