Example #1
0
 /// <summary>
 /// Constructs a prime factorization of the integer provided.
 /// <example>For example, 60 = 2^2 * 3 * 5.</example>
 /// </summary>
 /// <param name="value">The integer for which a prime factorization will be constructed.</param>
 public static PrimeFactorization PrimeFactorization(this long value)
 {
     return(MathHelpers.PrimeFactorization(value));
 }
Example #2
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) }));
        }
Example #3
0
        /// <summary>
        /// Gets all of the prime numbers up to and including the limit using the sieve of Atkin(https://en.wikipedia.org/wiki/Sieve_of_atkin).
        /// </summary>
        /// <param name="limit">The limit.</param>
        public static ICollection <BigInteger> PrimesByAtkin(BigInteger limit)
        {
            var primes = new HashSet <BigInteger> {
                2, 3, 5
            };

            if (limit <= 5)
            {
                return(primes.Where(m => m <= limit).ToArray());
            }

            var cachedPrimes = MemoryCache.Default.Get("LargestAtkin");

            if (cachedPrimes != null)
            {
                var castPrimes = (KeyValuePair <BigInteger, IOrderedEnumerable <BigInteger> >)cachedPrimes;
                if (limit == castPrimes.Key)
                {
                    return(castPrimes.Value.ToArray());
                }

                if (limit < castPrimes.Key)
                {
                    return(castPrimes.Value.Where(m => m <= limit).ToArray());
                }
            }

            /*var flip1 = new BigInteger[] { 1, 13, 17, 29, 37, 41, 49, 53 };
             * var flip2 = new BigInteger[] { 7, 19, 31, 43 };
             * var flip3 = new BigInteger[] { 11, 23, 47, 59 };*/
            var flip1 = new BigInteger[] { 1, 5 };
            var flip2 = new BigInteger[] { 7 };
            var flip3 = new BigInteger[] { 11 };

            // no built in sqrt, but MSDN offers this(http://msdn.microsoft.com/en-us/library/dd268263.aspx)
            var sqrt    = new BigInteger(Math.Ceiling(MathHelpers.Sqrt(limit)));
            var numbers = new HashSet <BigInteger>();
            Action <BigInteger> flipNumbers = (n) =>
            {
                if (!numbers.Add(n))
                {
                    numbers.Remove(n);
                }
            };

            for (BigInteger x = 1; x <= sqrt; x++)
            {
                for (BigInteger y = 1; y <= sqrt; y++)
                {
                    BigInteger n = (4 * (x * x)) + (y * y);
                    if (n <= limit && (flip1.Contains(n % 12)))
                    {
                        flipNumbers(n);
                    }

                    n = (3 * (x * x)) + (y * y);
                    if (n <= limit && (flip2.Contains(n % 12)))
                    {
                        flipNumbers(n);
                    }

                    n = (3 * (x * x)) - (y * y);
                    if (x > y && n <= limit && (flip3.Contains(n % 12)))
                    {
                        flipNumbers(n);
                    }
                }
            }

            var sortedNumbers = numbers.OrderBy(m => m);

            foreach (var sieveNumber in sortedNumbers)
            {
                if (!numbers.Contains(sieveNumber))
                {
                    continue;
                }

                primes.Add(sieveNumber);
                var squareSieve = sieveNumber * sieveNumber;
                var multiplier  = 1;
                while (multiplier * squareSieve <= limit)
                {
                    numbers.Remove(multiplier * squareSieve);
                    multiplier += 1;
                }
            }

            MemoryCache.Default["LargestAtkin"] = new KeyValuePair <BigInteger, IOrderedEnumerable <BigInteger> >(limit, primes.OrderBy(m => m));
            return(primes);
        }
Example #4
0
        public IEnumerable <BigInteger> PrimeFactorsByRationalSieve(BigInteger value)
        {
            var bound = value < 10000 ? Math.Ceiling(MathHelpers.Sqrt(value)) : Math.Ceiling(Math.Pow(BigInteger.Log(value, 2), 3));

            return(PrimeFactorsByRationalSieve(value, new BigInteger(bound)));
        }