Primes by double recursion
Posted on April 4, 2015
The idea is taken from here. Does it have to be this mind-bending?
class Primes
def initialize
@primes = {}
end
def is_prime(n)
if @primes.has_key?(n)
@primes[n]
else
@primes.store(n,
n > 1 &&
primes.take_while { |x| x <= Math.sqrt(n) }
.all? { |x| n % x != 0 })
end
end
def primes
[[2].lazy,
(3..Float::INFINITY).lazy
.select { |x| x % 2 != 0 && is_prime(x) }]
.lazy
.flat_map { |x| x }
end
end
p Primes.new.primes.take(10).force
#=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
flat_map { |x| x }
is the only known to me way to concatenate two lazy enumerators.
Having defined the lazy sequence of prime numbers I can easily find prime factors of a positive integer, but to avoid recursion it’s handy to define uninject
method first: