私は、各桁も素数である与えられた範囲内のすべての素数を見つける問題を解決しようとしています。PLINQを使って余分な効率を搾り取ることは可能でしょうか?
[1, 100]
の範囲では、は、それを満たすすべての数字ですので、8
です。2, 3, 5, 7, 23, 37, 53, 37
です。
私の現在のソリューションは、
// Yields all the numbers in the range [start, end] that could be primes,
// by taking into account the fact that a prime is either 2, 3, 6k + 1 or 6k - 1
static IEnumerable<long> PossiblePrimeNumbers(long start, long end)
{
if(start <= 2 && end >= 2)
yield return 2;
if(start <= 3 && end >= 3)
yield return 3;
for(long n = (start/6 + 1) * 6; ; n += 6)
{
if((n - 1) <= end)
yield return (n - 1);
if((n + 1) <= end)
yield return (n + 1);
else break;
}
}
// Map for fast checking of whether a digit 0, 1, ..., 9 is a prime
static bool[] IsPrimeDigit = { false, false, true, true, false, true, false, true, false, false };
// True or false depending on whether m is prime
static bool IsPrime(long m)
{
long boundary = (long)Math.Floor(Math.Sqrt(m));
bool isPrime = true;
for(long i = 2; i <= boundary; ++i)
{
if(m % i == 0)
{
isPrime = false;
break;
}
}
return isPrime;
}
// True or false depending on whether all the digits of m are prime and
// whether m itself is prime
static bool IsMegaprime(long m)
{
return m.ToString().All(c => IsPrimeDigit[c - '0']) && IsPrime(m);
}
// Counts the number of "megaprimes" (defined above) in the range [first, last]
static int NumberMegaprimes(long first, long last)
{
return PossiblePrimeNumbers(first, last).AsParallel().Count(m => IsMegaprime(m));
}
static void Main(String[] args)
{
long first = 1;
long last = 100;
Console.WriteLine(NumberMegaprimes(first, last)); // should print 8
}
正しく、あなたも、私が試してみて、それをスピードアップするために.AsParallel()
を追加したことがわかります。
これをスピードアップする明確な方法はありますか? (LINQを取り除く以外)
コードレビューの仕事は、コードが動作して以来のことです。 –