I'm working on creating a method, gap(g, m, n).
All 3 parameters are integers.
gap finds the first 2 consecutive prime numbers, between m and n, that have a difference of g.
For example, gap(2, 1, 10) => [3, 5]
In the range from m to n, 1..10, the first 2 consecutive prime numbers with a gap of 2 is [3,5].
If instead, it was gap(1, 1, 10) => [2,3]
and if it was gap(6, 1, 10) => nil
# method to check if a number is prime
def prime?(num)
(2..Math.sqrt(num).floor).each do |m|
if num % m == 0
return false
end
end
true
end
this method works by iterating through each number from 2, the smallest prime, to the square root of the parameter, checking to see if the parameter is evenly divisible by anything in that range. If it is, the method returns false.
# gap method
def gap(g, m, n)
if g.odd? && g > 1
return nil
end
primes = (m..n).select do |num|
num.odd? && prime?(num)
end
first = primes[0..-2].find_index do |x|
primes[primes.index(x) + 1] - x == g
end
[
primes[first],
primes[first+1]
] unless first.nil?
end
gap(2, 10000000, 11000000)
All prime numbers have a gap of either 2, 4, or a number made up of 2 and 4's added together. The only exception is the gap from 2-3.
So if the gap argument, g, given is a number like 3, which is both odd and greater than 1, the method automatically returns nil because no such prime gap exists.
Problem
My issue is that the method is too slow. By using the replit link above, you get a time of about 20 seconds. Apparently it is possible to get it to about 1 second.
I've tried optimizing by filtering out the even numbers already from m..n, which helped. But I'm just not sure how I can get this to go even faster.
What I'm thinking is before finding out every single prime number in m..n, I should check each iteration if the gap is correct, so once I find it I can just terminate the method without looking at unnecessary primes, but I'm not sure how to implement this.
Thanks for the help, and any general criticism of my code is welcome as well.