示例#1
0
        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) }));
        }
示例#2
0
 /// <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());
 }