Done puzzle 64
[project-euler.git] / primes.rb
index 7e2cfaacaa817e2418271d2544961271b0bb245a..496e79099c72f5e3d968e5798833d759d1b0e65c 100644 (file)
--- a/primes.rb
+++ b/primes.rb
@@ -3,6 +3,7 @@
 # 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
 
@@ -14,14 +15,20 @@ class Primes
   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
@@ -32,6 +39,8 @@ class Primes
     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
@@ -56,7 +65,7 @@ class Primes
   end
 
   def add_next_prime!
-    @primes.push next_prime
+    @primes << next_prime
   end
 
   # No longer needed: use Enumerable#take_while instead
@@ -95,10 +104,21 @@ class Primes
     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
 
 
@@ -107,5 +127,6 @@ class Integer
   
   def prime?
     @@primes.include? self
+    # @@primes.is_prime? self
   end
 end