예제 #1
0
        public ActionResult Problem35(ulong n)
        {
            var cal = new PrimeCalculator((uint)n / 3);

            cal.ExtendToMinimumGT(n);

            Func <ulong, bool> isCircular = (i) =>
            {
                ulong c         = i;
                uint  numDigits = Utils.NumOfDigits(c);
                ulong factor    = Utils.PowerOfTen(numDigits - 1);
                do
                {
                    ulong lower  = (c / 10);
                    ulong higher = (c % 10) * factor;   // Move rightmost digit to leftmost position
                    c = higher + lower;

                    if (!cal.IsPrimeInRange(c))
                    {
                        return(false);
                    }
                }while (c != i);

                return(true);
            };

            int cnt = cal.Primes.Count(isCircular);

            return(ViewAnswer(35, "The number of circular primes below " + n + " is", (uint)cnt));
        }
예제 #2
0
        public ActionResult Problem10(ulong n)
        {
            var cal = new PrimeCalculator((uint)n / 3);

            cal.ExtendToMinimumGT(n);
            var sum = cal.Primes.Sum() - cal.LastPrime;

            return(ViewAnswer(10, "The sum of all primes below " + n + " is", sum));
        }
예제 #3
0
        public ActionResult Problem49(uint n)
        {
            var cal = new PrimeCalculator();

            cal.ExtendToMinimumGT(9999);    // We know that the prime numbers will be 4-digit, as stated in problem

            // Algorithm:
            // 1) Find all prime numbers between 1000 to 9999, group them by permutations
            // 2) Skip if number of permutations in group is < n
            // 3) Find the all arithmetic sequences within group with len >= n
            //    - Not all prime numbers with same permutation will be part of the arithemetic sequence, for example,
            //      for 1487 -> 4817 -> 8147, 1847 won't particpate.

            // Steps 1
            var prime_grps = from p in cal.Primes
                             where p >= 1000 && p <= 9999
                             group p by p.GetSortedDigits() into g
                             select g;

            // Step 2
            prime_grps = prime_grps.Where(g => g.Count() >= n);

            // Step 3
            var matched_series = prime_grps.SelectMany(g => Utils.FindArithemeticSeries(g, n));

            // Stringify solution.  Each member of series separates by a comma.  Series separates by semicolon
            var sb = new StringBuilder();

            foreach (var series in matched_series)
            {
                foreach (var member in series)
                {
                    sb.Append(member);
                    sb.Append(',');
                }
                if (sb.Length > 0)
                {
                    sb.Remove(sb.Length - 1, 1);                   // Remove last comma
                }
                sb.Append(";");
            }
            if (sb.Length > 0)
            {
                sb.Remove(sb.Length - 1, 1);                       // Remove last semicolon
            }
            return(ViewAnswer(49, "4-digit primes which are permutations of each other", sb.ToString()));
        }
예제 #4
0
        public ActionResult Problem50(ulong n)
        {
            var cal = new PrimeCalculator(40000);

            cal.ExtendToMinimumGT(n);

            // Cumsums.. cumsum[i] = sum of primes[0 .. i]
            var primes  = cal.Primes;
            var cumsums = primes.CumSum().ToArray();

            // Calc sum from [fromPos, toPos]
            Func <int, int, ulong> calcSum = (fromPos, toPos) =>
            {
                int before = fromPos - 1;
                if (before >= 0)
                {
                    return(cumsums[toPos] - cumsums[before]);
                }
                else
                {
                    return(cumsums[toPos]);
                }
            };

            // Find end position for range to examine.
            int endPos;

            for (endPos = primes.Length - 1; endPos >= 0 && primes[endPos] > n; endPos--)
            {
                ;
            }

            // Loop through all possible values for [start, end] to find the longest range whose
            // sum is still a prime
            int   maxLen = 0, maxStart = 0;
            ulong maxNum = 0;

            for (int end = 0; end <= endPos; end++)
            {
                for (int start = 0; start < end; start++)
                {
                    int len = end - start + 1;
                    if (len < maxLen)
                    {
                        continue;
                    }

                    ulong sum = calcSum(start, end);
                    if (sum > n)
                    {
                        continue;
                    }

                    if (!cal.IsPrimeAutoExpand(sum))
                    {
                        continue;
                    }

                    maxLen   = len;
                    maxNum   = sum;
                    maxStart = start;
                }
            }

            int   maxEnd   = maxStart + maxLen - 1;
            ulong maxValue = calcSum(maxStart, maxEnd);
            var   s        = string.Format("{0} + .. + {1} = {2} len = {3}",
                                           primes[maxStart], primes[maxEnd], maxValue, maxEnd, maxLen);

            return(ViewAnswer(50, s, maxValue));
        }