これが可能かどうかはわかりませんが、質問する必要があります。私の数学的およびアルゴリズムのスキルは、ここで私を失敗させているようなものです: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 倍または 2 乗するなどして)
- ステップ 2 に進む
そして、最適には、そのステップ 2 は古い制限と新しい制限の間でのみ機能する必要があります。言い換えれば、最低の素数を何度も見つける必要はありません。
これを行う方法はありますか?x
私の主な問題は、y
たとえばこのアルゴリズムの内容がよくわからないことです。同様に、同じ種類のアルゴリズムを使用して、x
andy
をoldLimit
(最初は 1) に設定し、それを まで実行できnewLimit
ますか? または、それはどのように機能しますか?これに光を当てる明るい心はありますか?
これのポイントは、その制限を設定する必要がないようにすることです。たとえばTake()
、制限が十分に高いかどうかなどを気にせずに、Linq と必要な数の素数を使用できるようにします。