Я не знаю, возможно ли это или нет, но я просто должен спросить. Мои математические и алгоритмические навыки меня терпят неудачу: P
Теперь у меня есть этот класс, который генерирует простые числа до определенного предела:
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();
}
}
Теперь я хотел бы избавиться от предела, чтобы последовательность никогда не останавливалась (теоретически).
Я думаю, что это может произойти примерно так:
- Начните с некоторого тривиального предела
- Найти все простые числа до предела
- Допустим все новообретенные простые числа
- Увеличьте предел (путем удвоения или возведения в квадрат старого ограничения или чего-то подобного)
- Перейти к шагу 2
И оптимально, что второй шаг должен работать только между старым пределом и новым. Другими словами, ему не нужно снова и снова находить самые низкие числа.
Есть ли способ сделать это? Моя основная проблема заключается в том, что я не совсем понимаю, что x
и y
, например, есть в этом алгоритме. Например, могу ли я использовать один и тот же тип алгоритма, но установить x
и y
в oldLimit
(изначально 1) и запустить его до newLimit
? Или как это будет работать? Любые яркие умы с некоторым освещением, чтобы избавиться от этого?
Дело в том, что мне не нужно устанавливать этот предел. Так что я могу, например, использовать Linq и просто Take()
, но многие простые числа, в которых я нуждаюсь, не беспокоясь о том, является ли предел достаточно высоким и т.д.