# To use:
# require 'primes.rb'
# primes = Primes.instance
+# primes.load_primes 'primes_1000000.txt' # loads a file of precomputed primes
# primes.take(20) # returns the first 20 primes
# primes[10000] # returns the 10,001st prime
attr_accessor :mod_candidates
include Singleton
-
- def initialize(sieve_limit = 10000)
+
+ def initialize()
# @primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
- @primes = sieve sieve_limit
+ @primes = sieve
@cache_up_to = 30
@mod_candidates = ((1..@cache_up_to).collect {|x| x}).select {|x| [2, 3, 5].all? {|p| x % p != 0}}
end
+ def load_primes(cache_file)
+ if File.file?(cache_file)
+ @primes = File.readlines(cache_file).map {|l| l.chomp.to_i}
+ end
+ end
+
def primes
@primes.dup
end
index = @primes.bsearch_index {|i| i > limit} || @primes.length
while @primes[0..index].any? {|i| candidate % i == 0 }
candidate = next_candidate(candidate)
+ limit = Math.sqrt(candidate).floor
+ index = @primes.bsearch_index {|i| i > limit} || @primes.length
end
candidate
end
end
def add_next_prime!
- @primes.push next_prime
+ @primes << next_prime
end
# No longer needed: use Enumerable#take_while instead
while n >= @primes.last
add_next_prime!
end
- # @primes.include?(n)
!!(@primes.bsearch {|i| n - i})
end
+ # Use this if you're only testing a few primes and not needing to generate many more.
+ def is_prime?(n)
+ return true if n == 2
+ return false if n < 2
+ limit = Math.sqrt(n).floor
+ while @primes.last <= limit
+ add_next_prime!
+ end
+ index = @primes.bsearch_index {|i| i > limit} || @primes.length
+ @primes[0..index].none? {|i| n % i == 0}
+ end
+
end
+
+class Integer
+ @@primes = Primes.instance
+
+ def prime?
+ @@primes.include? self
+ # @@primes.is_prime? self
+ end
+end