private int PrimeFactors(int n)
        {
            var sieve = new PrimeSieve(n);
            var primes = sieve.GetPrimeCollection(3, n);

            int maxBound = n / 2, count = 0;

            foreach (var prime in primes)
            {
                var m = prime > maxBound ? 1 : 0;

                if (prime <= maxBound)
                {
                    var q = n;
                    while (q >= prime)
                    {
                        m += q /= prime;
                    }
                }

                this.primeList[count] = prime;
                this.multiList[count++] = m;
            }
            return count;
        }
        private int PrimeFactors(int n)
        {
            var sieve           = new PrimeSieve(n);
            var primeCollection = sieve.GetPrimeCollection(2, n);

            int maxBound = n / 2, count = 0;

            foreach (var prime in primeCollection)
            {
                var m = prime > maxBound ? 1 : 0;

                if (prime <= maxBound)
                {
                    var q = n;
                    while (q >= prime)
                    {
                        m += q /= prime;
                    }
                }

                this.primeList[count]   = prime;
                this.multiList[count++] = m;
            }

            return(count);
        }
        private void PrimeFactors(int n)
        {
            var maxBound = n / 3;
            var lastList = this.primeList.Length - 1;
            var start = this.tower[1] == 2 ? 1 : 0;
            var sieve = new PrimeSieve(n);

            for (var section = start; section < this.primeList.Length; section++)
            {
                var primes = sieve.GetPrimeCollection(this.tower[section] + 1, this.tower[section + 1]);

                foreach (var prime in primes)
                {
                    this.primeList[section][this.listLength[section]++] = prime;
                    if (prime > maxBound) continue;

                    var np = n;
                    do
                    {
                        var k = lastList;
                        var q = np /= prime;

                        do if ((q & 1) == 1) //if q is odd
                            {
                                this.primeList[k][this.listLength[k]++] = prime;
                            }
                        while (((q >>= 1) > 0) && (prime <= this.bound[--k]));

                    } while (prime <= np);
                }
            }
        }
        private static XInt Swing(PrimeSieve sieve, int n)
        {
            var primorial = Task.Factory.StartNew <XInt>(() => sieve.GetPrimorial(n / 2 + 1, n));
            var count     = 0;
            var rootN     = XMath.FloorSqrt(n);
            var aPrimes   = sieve.GetPrimeCollection(3, rootN);
            var bPrimes   = sieve.GetPrimeCollection(rootN + 1, n / 3);

            var primeList = new int[aPrimes.NumberOfPrimes + bPrimes.NumberOfPrimes];

            foreach (var prime in aPrimes)
            {
                int q = n, p = 1;

                while ((q /= prime) > 0)
                {
                    if ((q & 1) == 1)
                    {
                        p *= prime;
                    }
                }

                if (p > 1)
                {
                    primeList[count++] = p;
                }
            }

            foreach (var prime in bPrimes.Where(prime => ((n / prime) & 1) == 1))
            {
                primeList[count++] = prime;
            }

            var primeProduct = XMath.Product(primeList, 0, count);

            return(primeProduct * primorial.Result);
        }
        private static XInt Swing(PrimeSieve sieve, int n)
        {
            var primorial = Task.Factory.StartNew<XInt>(() => sieve.GetPrimorial(n / 2 + 1, n));
            var count = 0;
            var rootN = XMath.FloorSqrt(n);
            var aPrimes = sieve.GetPrimeCollection(3, rootN);
            var bPrimes = sieve.GetPrimeCollection(rootN + 1, n / 3);

            var primeList = new int[aPrimes.NumberOfPrimes + bPrimes.NumberOfPrimes];

            foreach (var prime in aPrimes)
            {
                int q = n, p = 1;

                while ((q /= prime) > 0)
                {
                    if ((q & 1) == 1)
                    {
                        p *= prime;
                    }
                }

                if (p > 1)
                {
                    primeList[count++] = p;
                }
            }

            foreach (var prime in bPrimes.Where(prime => ((n / prime) & 1) == 1))
            {
                primeList[count++] = prime;
            }

            var primeProduct = XMath.Product(primeList, 0, count);
            return primeProduct * primorial.Result;
        }
Ejemplo n.º 6
0
        private void PrimeFactors(int n)
        {
            var maxBound = n / 3;
            var lastList = this.primeList.Length - 1;
            var start    = this.tower[1] == 2 ? 1 : 0;
            var sieve    = new PrimeSieve(n);

            for (var section = start; section < this.primeList.Length; section++)
            {
                var primes = sieve.GetPrimeCollection(this.tower[section] + 1, this.tower[section + 1]);

                foreach (var prime in primes)
                {
                    this.primeList[section][this.listLength[section]++] = prime;
                    if (prime > maxBound)
                    {
                        continue;
                    }

                    var np = n;
                    do
                    {
                        var k = lastList;
                        var q = np /= prime;

                        do
                        {
                            if ((q & 1) == 1) //if q is odd
                            {
                                this.primeList[k][this.listLength[k]++] = prime;
                            }
                        }while (((q >>= 1) > 0) && (prime <= this.bound[--k]));
                    } while (prime <= np);
                }
            }
        }
        public XInt Factorial(int n)
        {
            if (n < 20) { return XMath.Factorial(n); }

            var rootN = XMath.FloorSqrt(n);
            var log2N = XMath.FloorLog2(n);
            var section = new XInt[log2N + 1];

            for (var i = 0; i < section.Length; i++)
            {
                section[i] = XInt.One;
            }

            var sieve = new PrimeSieve(n);
            var primes = sieve.GetPrimeCollection(3, rootN);

            foreach (var prime in primes)
            {
                int k = 0, m = 0, q = n;

                do
                {
                    m += q /= prime;

                } while (q >= 1);

                while (m > 0)
                {
                    if ((m & 1) == 1)
                    {
                        section[k] *= prime;
                    }
                    m = m / 2;
                    k++;
                }
            }

            var j = 2;
            var low = n;

            while (low != rootN)
            {
                var high = low;
                low = n / j++;

                if (low < rootN) { low = rootN; }

                var primorial = sieve.GetPrimorial(low + 1, high);

                if (primorial != XInt.One)
                {
                    int k = 0, m = j - 2;

                    while (m > 0)
                    {
                        if ((m & 1) == 1)
                        {
                            section[k] *= primorial;
                        }
                        m = m / 2;
                        k++;
                    }
                }
            }

            var factorial = section[log2N];
            for (var i = log2N - 1; i >= 0; --i)
            {
                factorial = XInt.Pow(factorial,2) * section[i];
            }

            var exp2N = n - XMath.BitCount(n);
            return factorial << exp2N;
        }
        public XInt Factorial(int n)
        {
            if (n < 20)
            {
                return(XMath.Factorial(n));
            }

            var rootN   = XMath.FloorSqrt(n);
            var log2N   = XMath.FloorLog2(n);
            var section = new XInt[log2N + 1];

            for (var i = 0; i < section.Length; i++)
            {
                section[i] = XInt.One;
            }

            var sieve  = new PrimeSieve(n);
            var primes = sieve.GetPrimeCollection(3, rootN);

            foreach (var prime in primes)
            {
                int k = 0, m = 0, q = n;

                do
                {
                    m += q /= prime;
                } while (q >= 1);

                while (m > 0)
                {
                    if ((m & 1) == 1)
                    {
                        section[k] *= prime;
                    }
                    m = m / 2;
                    k++;
                }
            }

            var j   = 2;
            var low = n;

            while (low != rootN)
            {
                var high = low;
                low = n / j++;

                if (low < rootN)
                {
                    low = rootN;
                }

                var primorial = sieve.GetPrimorial(low + 1, high);

                if (primorial != XInt.One)
                {
                    int k = 0, m = j - 2;

                    while (m > 0)
                    {
                        if ((m & 1) == 1)
                        {
                            section[k] *= primorial;
                        }
                        m = m / 2;
                        k++;
                    }
                }
            }

            var factorial = section[log2N];

            for (var i = log2N - 1; i >= 0; --i)
            {
                factorial = XInt.Pow(factorial, 2) * section[i];
            }

            var exp2N = n - XMath.BitCount(n);

            return(factorial << exp2N);
        }