C #: Jak zrobić Sieve of Atkin inkrementalnie

Nie wiem, czy to jest możliwe, czy nie, ale muszę tylko zapytać. Moje umiejętności matematyczne i algorytmiczne zawodzą mnie tutaj: P

Chodzi o to, że teraz mam tę klasę, która generuje liczby pierwsze do pewnego limitu:

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();
    }
}

Teraz chciałbym pozbyć się limitu, aby sekwencja nigdy się nie zatrzymała (teoretycznie).

Myślę, że może to wyglądać mniej więcej tak:

Zacznij od jakiegoś trywialnego limituZnajdź wszystkie liczby pierwsze do limituWydaj wszystkie nowe liczby pierwszeZwiększ limit (podwajając lub zwiększając stary limit lub coś podobnego)Przejdź do kroku 2

I optymalnie, że krok drugi powinien działać tylko między starym limitem a nowym. Innymi słowy, nie powinien ponownie i ponownie znajdować najniższych liczb pierwszych.

Czy można to zrobić w jakiś sposób? Moim głównym problemem jest to, że nie do końca rozumiem cox iy na przykład jest w tym algorytmie. Na przykład, czy mógłbym użyć tego samego algorytmu, ale ustawionyx iy dooldLimit (początkowo 1) i uruchom gonewLimit? A jak by to działało? Jakieś jasne umysły z odrobiną światła na to?

Chodzi o to, że nie będę musiał ustalać tego limitu. Żeby na przykład użyć Linq i po prostuTake() jednak potrzebuję wielu liczb pierwszych, nie martwiąc się, czy limit jest wystarczająco wysoki, itd.

questionAnswers(4)

yourAnswerToTheQuestion