예제 #1
0
        /* calculate least common multiple
         * http://www.math.com/school/subject1/lessons/S1U3L3DP.html
         * basically, get the prime factors of each number in the set,
         * and multiply them together. if a factor appears more than once,
         * multiply it the max number of times it appears in a single factor
         * example:
         * find LCM of 3, 9, 21
         * prime factors:
         * 3: 3
         * 9: 3 × 3
         * 21: 3 × 7
         * solution = 3 x 3 x 7 = 63
         */
        public static int LCMOfRange(int lo, int hi)
        {
            int[]  numbers = Enumerable.Range(lo, hi - lo + 1).ToArray();
            long[] primes  = OP.Primes(hi).ToArray();
            Dictionary <int, int> factorsWithCounts = new Dictionary <int, int>(numbers.Length);

            //TODO nonrepeatedFactors can be replaced by a running product (just use division instead of List.Remove())
            foreach (int num in numbers)
            {
                //TODO THIS IS DAMN UGLY!!!
                // REPLACE with single dictionary with counts. the 2-list thing is stupid

                /*
                 * single dict, for each N do a simple key check for count=1,
                 *
                 */
                Dictionary <int, int> factors = OP.FactorToPrimes(num, primes).GroupBy(p => p).ToDictionary(k => (int)k.Key, v => v.Count());
                foreach (var i in factors)
                {
                    int factor = i.Key;
                    int count  = i.Value;
                    if (factorsWithCounts.ContainsKey(factor))
                    {
                        if (count > factorsWithCounts[factor])
                        {
                            factorsWithCounts[factor] = count;
                        }
                    }
                    else
                    {
                        factorsWithCounts.Add(factor, count);
                    }
                }
#if verbose
                string foo = String.Format("Prime factor counts for {0}: {1}", num, String.Join(",", factors.Select(o => $"{o.Key} ({o.Value})")));
                System.Diagnostics.Debug.WriteLine(foo);
#endif
            }

#if verbose
            string allFactorsDebug = Utilities.StringifyDict <int, int>(factorsWithCounts, "factorsWithCounts");
            System.Diagnostics.Debug.WriteLine(allFactorsDebug);
#endif
            int lcm = 1;
            foreach (var kvp in factorsWithCounts)
            {
                lcm *= (int)kvp.Key.Pow(kvp.Value);
            }

            return(lcm);
        }
예제 #2
0
        public static long GetNthPrime(int n, int segmentSize = DEFAULT_SLICE_SIZE)
        {
            // http://www.thelowlyprogrammer.com/2012/08/primes-part-2-segmented-sieve.html


            List <long> primes = new List <long>(n);

            primes.AddRange(OP.Primes(segmentSize));

            //do segmented sieve passes with ranges of DEFAULT_SLICE_SIZE length
            //until our list of primes reaches N length.
            int rangeStart = 1;

            while (primes.Count() <= n)
            {
                rangeStart += segmentSize;
                primes.AddRange(OP.RangeSieve(rangeStart, segmentSize, primes));
            }
            // remember to subtract 1 to get Nth from 0-based list
            return(primes[n - 1]);
        }