public IEnumerable <BigInteger> PrimeFactorsByRationalSieve(BigInteger value, BigInteger bound) { if (IsPrimeByMillerRabin(value, 10)) { return new[] { value } } ; var primes = PrimesByAtkin(bound); var suitablePrimes = primes.Where(m => value % m == 0); if (suitablePrimes.Any()) { var product = suitablePrimes.Aggregate(BigInteger.One, (accumulator, current) => accumulator * current); return(suitablePrimes.Union(this.PrimeFactorsByRationalSieve(value / product, bound))); } var zValues = new Dictionary <BigInteger, List <List <int> > >(); for (int i = 1; i < value && zValues.Count < (primes.Count + 3); i++) { if (!IsBSmooth(i, bound) || !IsBSmooth(i + value, bound)) { continue; } var leftList = new List <int>(primes.Count); var rightList = new List <int>(primes.Count); foreach (var prime in primes) { var exponent = 1; while (i % BigInteger.Pow(prime, exponent) == 0) { exponent += 1; } leftList.Add(exponent - 1); exponent = 1; while ((i + value) % BigInteger.Pow(prime, exponent) == 0) { exponent += 1; } rightList.Add(exponent - 1); } zValues.Add(i, new List <List <int> > { leftList, rightList }); } if (zValues.Any() == false) { return(suitablePrimes); } var allEvens = zValues.Values.FirstOrDefault(m => m[0].All(n => n % 2 == 0) && m[1].All(n => n % 2 == 0)); if (allEvens == null) { for (int i = 0; i < zValues.Count && allEvens == null; i++) { for (int n = i + 1; n < zValues.Count && allEvens == null; n++) { var leftList = new List <int>(primes.Count); var rightList = new List <int>(primes.Count); for (int j = 0; j < primes.Count; j++) { var leftAddition = zValues.ElementAt(i).Value[0][j] + zValues.ElementAt(n).Value[0][j]; var rightAddition = zValues.ElementAt(i).Value[1][j] + zValues.ElementAt(n).Value[1][j]; if (leftAddition == rightAddition) { leftList.Add(0); rightList.Add(0); } else { leftList.Add(leftAddition); rightList.Add(rightAddition); } } if (leftList.All(m => m % 2 == 0) && rightList.All(m => m % 2 == 0)) { allEvens = new List <List <int> > { leftList, rightList } } ; } } } var leftProduct = BigInteger.One; var rightProduct = BigInteger.One; for (int i = 0; i < primes.Count; i++) { leftProduct *= BigInteger.Pow(primes.ElementAt(i), allEvens[0][i]); rightProduct *= BigInteger.Pow(primes.ElementAt(i), allEvens[1][i]); } var leftSquare = MathHelpers.Sqrt(leftProduct); var rightSquare = MathHelpers.Sqrt(rightProduct); return(suitablePrimes.Union(new[] { GreatestCommonFactor(Math.Abs((int)leftSquare - (int)rightSquare), value), GreatestCommonFactor((int)leftSquare + (int)rightSquare, value) })); }
/// <summary> /// Calculates the sum of the digits of the number 2^1000 /// </summary> static void P016() { Console.WriteLine((from i in (BigInteger.Pow(2, 1000)).ToString() select(int) Char.GetNumericValue(i)).Sum()); }
/// <summary> /// Calculates the number of n-digit positive integers which are also an nth power /// </summary> static void P063() { Console.WriteLine((from i in Enumerable.Range(1, 9) select(from j in Enumerable.Range(1, 25) where BigInteger.Pow(i, j).ToString().Length == j select 1).Count()).Sum()); }