I don't know if this is possible or not, but I just gotta ask. My mathematical and algorithmic skills are kind of failing me here :P
The thing is I now have this class that generates prime numbers up to a certain limit:
public class Atkin : IEnumerable<ulong>
{
private readonly List<ulong> primes;
private readonly ulong limit;
public Atkin(ulong limit)
{
this.limit = limit;
primes = new List<ulong>();
}
private void FindPrimes()
{
var isPrime = new bool[limit + 1];
var sqrt = Math.Sqrt(limit);
for (ulong x = 1; x <= sqrt; x++)
for (ulong y = 1; y <= sqrt; y++)
{
var n = 4*x*x + y*y;
if (n <= limit && (n % 12 == 1 || n % 12 == 5))
isPrime[n] ^= true;
n = 3*x*x + y*y;
if (n <= limit && n % 12 == 7)
isPrime[n] ^= true;
n = 3*x*x - y*y;
if (x > y && n <= limit && n % 12 == 11)
isPrime[n] ^= true;
}
for (ulong n = 5; n <= sqrt; n++)
if (isPrime[n])
{
var s = n * n;
for (ulong k = s; k <= limit; k += s)
isPrime[k] = false;
}
primes.Add(2);
primes.Add(3);
for (ulong n = 5; n <= limit; n++)
if (isPrime[n])
primes.Add(n);
}
public IEnumerator<ulong> GetEnumerator()
{
if (!primes.Any())
FindPrimes();
foreach (var p in primes)
yield return p;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Now, what I would like is to get rid of the limit so that the sequence would never stop (theoretically).
I am thinking it could go something like this:
- Start with some trivial limit
- Find all the primes up to the limit
- Yield all the newfound primes
- Increase the limit (by doubling or squaring the old limit or something like that)
- Goto step 2
And optimally that step two should only have to work between the old limit and the new one. In other words it shouldn't have to find the lowest primes again and again.
Is there a way this can be done? My main problem is that I don't quite understand what x
and y
for example is in this algorithm. Like, could I just use the same algorithm kind of but set x
and y
to oldLimit
(initially 1) and run it up to newLimit
? Or how would that work? Any bright minds with some light to shed on this?
The point of this is so that I won't have to set that limit. So that I can for example use Linq and just Take()
however many primes I need, not worrying about if the limit is high enough, et cetera.