private void SieveOfEratosthenesFactorizer(int limit, int passes, int start, int end) { var factorizer = new SieveOfEratosthenesFactorizer(limit); for (int p = 0; p < passes; ++p) { for (int n = start; n <= end; ++n) { factorizer.GetPrimeFactors(n).ToArray(); } } }
public void GetPrimeFactors_AgreesWithNaiveFactorizer() { var sieveFactorizer = new SieveOfEratosthenesFactorizer(3481); var trialDivisionFactorizer = new TrialDivisionFactorizer(3481); for (int n = 0; n <= 3481; ++n) { CollectionAssert.AreEquivalent( NaivePrimeDeciderProviderFactorizer.GetPrimeFactors(n).ToArray(), sieveFactorizer.GetPrimeFactors(n).ToArray()); CollectionAssert.AreEquivalent( NaivePrimeDeciderProviderFactorizer.GetPrimeFactors(n).ToArray(), trialDivisionFactorizer.GetPrimeFactors(n).ToArray()); } }
public void GetPrimeFactors_AgreesWithKnownOutput() { var sieveFactorizer = new SieveOfEratosthenesFactorizer(1000); var trialDivisionFactorizer = new TrialDivisionFactorizer(1000); foreach (var numberPrimeFactorsPair in _numberPrimeFactorsPairs) { int number = numberPrimeFactorsPair.Item1; int[] primeFactors = numberPrimeFactorsPair.Item2; CollectionAssert.AreEquivalent(primeFactors, sieveFactorizer.GetPrimeFactors(number).ToArray()); CollectionAssert.AreEquivalent(primeFactors, trialDivisionFactorizer.GetPrimeFactors(number).ToArray()); CollectionAssert.AreEquivalent(primeFactors, NaivePrimeDeciderProviderFactorizer.GetPrimeFactors(number).ToArray()); } }
public IEnumerable <long> GetPrimeFactors(long n) { if (n <= _sieveFactorizer.Limit) { foreach (long primeFactor in _sieveFactorizer.GetPrimeFactors((int)n)) { yield return(primeFactor); } } else { foreach (long prime in _sieveFactorizer.Primes) { // Check for factors up to sqrt(n), as non-primes with a factor larger than that // must also have a factor less than that, otherwise they'd multiply together to // make a number greater than n. The fact that n is getting smaller doesn't matter. // If this condition stops the loop, what remains of n is a single prime factor. // All primes less than 'prime' were already divided out, so for n to have multiple // prime factors they'd have to all be >= 'prime', but in that case the loop // wouldn't stop here. if (prime * prime > n) { break; } while (n % prime == 0) { yield return(prime); n /= prime; } // All the prime factors have been extracted, so stop looking. if (n == 1) { yield break; } } // The loop above was broken out of (before n == 1), so the original n, or what // remains of it, is prime. yield return(n); } }