Rather than scraping a Ruby version of this algorithm off the net I wanted to create my own based on its description here. However I cannot figure out two things
def primeSieve(n)
primes = Array.new
for i in 0..n-2
primes[i] = i+2
end
index = 0
while Math.sqrt(primes.last).ceil > primes[index]
(primes[index] ** 2).step(primes.length - 1, primes[index])
{|x| x % primes[index] == 0 ? primes.delete(x) : ""}
index += 1
end
primes
end
- Why it doesn't iterate to the end of the array?
- According to the description in the link above the loop should be broken out of when the squareroot of the last element in the array is greater than the current prime - mine does this one before.
I'm fairly sure it has something to do with the delete operation modifying the length of the array. For example my function currently yields 2,3,5,7,9,10 when I enter n=10 which is obviously not correct. Any suggestions on how I can go about alterating this to make it work like it's supposed to?
The following seems to work. I took out the floating point arithmetic and squared instead of square rooting. I also replaced the deletion loop with a "select" call.
Edit: I think I figured out how you're trying to do this. The following seems to work, and seems to be more in line with your original approach.
There's a faster implementation at www.scriptol.org:
I think it can be improved on slightly thus:
...largely because of the faster array initialisation, I think, but it's marginal. (I added
#compact
to both to eliminate the unwantednil
s)This is a reference for those who are interested. The code is from this site.
This code uses Sieve of Eratosthenes as well.
And here is another one.
This is a pretty straightforward implementation of the Wikipedia article pseudocode, using a bit array.
or
There may be a way to use inject here but the inception thing hurts my head today.