コード例 #1
0
        public static void Performance()
        {
            var rnd = new Random(1337);

            const int maxA = 100000;

            //var A = Enumerable.Repeat(0, 10).Select(_ => (ulong)rnd.Next(1, maxA)).ToArray();
            var A = new ulong[] { 2ul, 3ul, 5ul, 7ul, 11ul, 13ul };

            while (true)
            {
                var mul = A.Aggregate(1ul, (x, y) => x * y);
                if (mul < 100000)
                {
                    break;
                }
                A[A.IndexOfElementWithMax()] = (ulong)rnd.Next(1, maxA);
            }
            var L = (ulong)rnd.Next(1, 10000000);
            var R = L + (ulong)rnd.Next(0, 1000000);

            Console.WriteLine("Generated:");
            Console.WriteLine(A.Join());
            Console.WriteLine(new { L, R });
            Console.WriteLine(new { lcm = A.Aggregate(1ul, (x, y) => LCM(x, y)) });

            var timer = Stopwatch.StartNew();

            Console.WriteLine(SolveLcm2(A, L, R));
            Console.WriteLine("Solve time: " + timer.ElapsedMilliseconds);
        }
コード例 #2
0
        public override string Solve()
        {
            //int limit = 100;
            //BigInt number = 1;
            //for (int i = 2; i < limit; i++)
            //    number *= i;
            //return SumDigits(number.ToString());

            const ulong limit = 100;
            // n! <= e*((n+1)/e)^(n+1)
            int limitDigitsCount = (int)Math.Ceiling(Math.Log10(Math.E * Math.Pow((double)(limit + 1) / Math.E, limit + 1)));

            // or (int)Math.Ceiling((double)(limit + 1) * Math.Log10(limit + 1) - (double)limit * Math.Log10(Math.E));
            ulong[] digits = new ulong[limitDigitsCount + 1];
            for (int i = 0; i < limitDigitsCount; i++)
            {
                digits[i] = 0;
            }

            digits[0] = 1;
            ulong digitCount = 1;

            for (ulong i = 2; i <= limit; i++)
            {
                Tools.Tools.MulDigitsNumber(digits, ref digitCount, i);
                //ulong toto = 0;
                //foreach (ulong digit in digits)
                //    toto += digit;
                //Console.WriteLine(i + "->" + toto);
            }
            return(digits.Aggregate <ulong, ulong>(0, (current, digit) => current + digit).ToString(CultureInfo.InvariantCulture));
        }
コード例 #3
0
ファイル: Problem72.cs プロジェクト: SinaC/ProjectEuler
        public override string Solve()
        {
            // 1: /
            // 2: 1/2
            // 3: 1/3 2/3
            // 4: 1/4 3/4
            // 5: 1/5 2/5 3/5 4/5
            // 6: 1/6 5/6
            // 7: 1/7 2/7 3/7 4/7 5/7 6/7
            // 8: 1/8 3/8 5/8 7/8
            // 9: 1/9 2/9 4/9 5/9 7/9 8/9
            // number of reduced fraction with denominator d = phi(d)


            //// Brute-force too slow
            //ulong limit = 1000000;
            //bool[] sieve = BuildSieve(limit);
            //ulong sum = 0;
            //for (ulong d = 2; d <= limit; d++)
            //    sum += Phi(sieve,d);
            //return sum;

            // Initialize phi(n) with n
            // each time we find a prime, for each multiple of this prime we'll multiply phi(prime*multiple) by (1-1/prime)
            const ulong limit = 1000000;

            bool[] sieve = new bool[limit + 1];
            for (int i = 0; i < sieve.Length; i++)
            {
                sieve[i] = true;
            }
            ulong[] phi = new ulong[limit + 1];
            for (int i = 0; i < phi.Length; i++)
            {
                phi[i] = (ulong)i;
            }
            // some values are hard-coded
            sieve[0] = false;
            sieve[1] = false;
            // Phi sieve
            for (ulong n = 2; n <= limit; n++)
            {
                if (sieve[n])
                {
                    phi[n] = n - 1; // phi of a prime is prime-1
                    for (ulong multiple = 2; n *multiple <= limit; multiple++)
                    {
                        sieve[n * multiple] = false;
                        phi[n * multiple]   = (phi[n * multiple] * (n - 1)) / n; // a*(1-1/p) = a*(p-1)/p
                    }
                }
            }
            ulong sum = phi.Aggregate <ulong, ulong>(0, (current, p) => current + p);

            return((sum - 1).ToString(CultureInfo.InvariantCulture)); // -1 because 1 doesn't give a reduced fraction
        }
コード例 #4
0
ファイル: Problem153.cs プロジェクト: SinaC/ProjectEuler
        public ulong Solve2()
        {
            // http://oeis.org/A132994

            // n/(a+bi) = na/(a^2+b^2) - i * nb/(a^2+b^2)
            // na and nb divisible by a^2+b^2
            // na/(a^2+b^2) > 0  with n positive integer, a is also positive integer and b is integer
            // b = 0, a = 1 -> 1 solution
            // b = 0, a = n -> 1 solution
            // sum(b) = 0 because if a,b is a solution then a,-b is also a solution
            const ulong limit = 16;
            ulong       sum   = 0;

            ulong[] count = new ulong[limit + 1];

            for (ulong n = 1; n <= limit; n++)
            {
                //Console.WriteLine(n);
                // b = 0, a = n
                Console.Write(n + "," + 0 + " | ");
                sum      += n; // n,0
                count[n] += n;
                for (ulong a = 1; a <= n / 2; a++)
                {
                    ulong upperBound = (ulong)(Math.Sqrt(n * n - a * a) + 0.5);
                    // b = 0
                    if (0 == (n % a))
                    {
                        Console.Write(a + "," + 0 + " | ");
                        sum      += a; // a,0
                        count[n] += a;
                    }
                    // b > 0
                    for (ulong b = 1; b <= upperBound; b++)
                    {
                        ulong divisor = a * a + b * b;
                        if (0 == ((n * a) % divisor) && 0 == ((n * b) % divisor))
                        {
                            Console.Write(a + "," + b + " | ");
                            Console.Write(a + ",-" + b + " | ");
                            sum      += a + b; // a,b and a,-b
                            count[n] += a + b;
                        }
                    }
                }
                Console.WriteLine();
            }
            for (int i = 0; i < count.Length; i++)
            {
                Console.WriteLine("{0}: {1}", i, count[i]);
            }
            ulong s = count.Aggregate((ulong)0, (n, i) => n + i);

            return(sum);
        }
コード例 #5
0
        public override void Solve()
        {
            var maxMemory = inputData.Select(w => w.MemoryIndex).Max();
            var memory    = new ulong[maxMemory + 1];

            foreach (var memeoryData in inputData)
            {
                var numberAfterMask = NumberToCharConverterDay14.ApplyMaskToNumber(memeoryData.Number, memeoryData.Mask);
                memory[memeoryData.MemoryIndex] = NumberToCharConverterDay14.ConvertCharArrayToNumber(numberAfterMask);
            }
            solution = memory.Aggregate((a, c) => a + c);
        }
コード例 #6
0
        public ulong Solve2()
        {
            const ulong limit = 1000000;

            //const ulong limit = 25;

            ulong[] primes = Primes.SoE.Primes(limit).ToArray();
            ulong[] array  = new ulong[limit];

            for (ulong i = 2; i < limit; i++)
            {
                CalculateMDRS(primes, array, i);
            }

            return(array.Aggregate((ulong)0, (n, i) => n + i));
        }
コード例 #7
0
ファイル: Problem56.cs プロジェクト: SinaC/ProjectEuler
        public override string Solve()
        {
            //ulong bestDigitSum = 0;
            //for ( uint i = 90; i <= 99; i++ ) {
            //    for (uint j = 90; j <= 99; j++) {
            //        BigInt power = BigInt.Power(i, j);
            //        ulong sum = SumDigits(power.ToString());
            //        if (sum > bestDigitSum)
            //            bestDigitSum = sum;
            //    }
            //return bestDigitSum;

            // biggest number = 99^99
            // number of digits = floor(99*log10(99))+1
            const ulong limit            = 99;
            ulong       limitDigitsCount = (ulong)((double)limit * Math.Log10(limit)) + 1;

            ulong[] digits       = new ulong[limitDigitsCount];
            ulong   bestDigitSum = 0;

            //ulong bestBase = 0;
            //ulong bestExponent = 0;
            for (uint b = 90; b <= limit; b++)
            { // 90->99
                for (int i = 0; i < digits.Length; i++)
                {
                    digits[i] = 0;
                }
                digits[0] = 1; // starts with 1
                ulong digitCount = 1;
                for (ulong e = 1; e <= limit; e++)
                { // compute each power of base
                    Tools.Tools.MulDigitsNumber(digits, ref digitCount, b);
                    ulong sum = digits.Aggregate <ulong, ulong>(0, (current, digit) => current + digit);
                    if (sum > bestDigitSum)
                    {
                        //bestBase = b;
                        //bestExponent = e;
                        bestDigitSum = sum;
                    }
                }
            }
            return(bestDigitSum.ToString(CultureInfo.InvariantCulture));
        }
コード例 #8
0
ファイル: Problem105.cs プロジェクト: SinaC/ProjectEuler
        public override string Solve()
        {
            ulong total = 0;

            foreach (string line in Lines)
            {
                string[] numbers = line.Split(',');
                ulong[]  set     = new ulong[numbers.Length];
                int      idx     = 0;
                foreach (string number in numbers)
                {
                    set[idx++] = Convert.ToUInt64(number);
                }
                if (Tools.Tools.IsSpecialSet(set))
                {
                    total = set.Aggregate(total, (current, val) => current + val);
                }
            }
            return(total.ToString(CultureInfo.InvariantCulture));
        }
コード例 #9
0
ファイル: Problem61.cs プロジェクト: SinaC/ProjectEuler
        public override string Solve()
        {
            const ulong lowerBound = 1000; // 4 digits
            const ulong upperBound = 9999; // 4 digits

            List <ulong> triangles   = BuildPolygonalList(lowerBound, upperBound, Tools.Tools.TriangleIndex, Tools.Tools.Triangle);
            List <ulong> squares     = BuildPolygonalList(lowerBound, upperBound, Tools.Tools.SquareIndex, Tools.Tools.Square);
            List <ulong> pentagonals = BuildPolygonalList(lowerBound, upperBound, Tools.Tools.PentagonalIndex, Tools.Tools.Pentagonal);
            List <ulong> hexagonals  = BuildPolygonalList(lowerBound, upperBound, Tools.Tools.HexagonalIndex, Tools.Tools.Hexagonal);
            List <ulong> heptagonals = BuildPolygonalList(lowerBound, upperBound, Tools.Tools.HeptagonalIndex, Tools.Tools.Heptagonal);
            List <ulong> octogonals  = BuildPolygonalList(lowerBound, upperBound, Tools.Tools.OctogonalIndex, Tools.Tools.Octogonal);

            // abcd -> cdef -> efgh -> ghij -> ijkl -> klab
            // loop among octogonals ==> abcd
            // search in other collections for cdef
            // search in other collections for efgh
            // search in other collections for ghij
            // search in other collections for ijkl
            // search in last collection for klab
            ulong sum = 0;

            foreach (ulong octogonal in octogonals)
            {
                //Console.WriteLine("======");
                List <List <ulong> > collectionsLeft = new List <List <ulong> >(new [] { heptagonals, hexagonals, pentagonals, squares, triangles });
                ulong[] items = new ulong[collectionsLeft.Count + 1];
                items[0] = octogonal;
                bool fFound = Sub(octogonal, collectionsLeft, octogonal /*, 1*/, ref items);
                if (fFound)
                {
                    //foreach (ulong item in items)
                    //{
                    //    //Console.Write(item + "->");
                    //    sum += item;
                    //}
                    sum = items.Aggregate(sum, (current, item) => current + item);
                    break;
                }
            }
            return(sum.ToString(CultureInfo.InvariantCulture));
        }
コード例 #10
0
        public override ValueTask Part01(IConsole console)
        {
            var maskMatcher = new Regex(@"mask\s=\s(?<mask>[X01]+)");
            var memMatcher  = new Regex(@"mem\[(?<memIndex>\d+)]\s=\s(?<value>\d+)");

            string mask = string.Empty;
            var    mem  = new ulong[ushort.MaxValue];

            foreach (var inputLine in day14Input.Split(Environment.NewLine).Where(s => !string.IsNullOrWhiteSpace(s)))
            {
                var maskMatch = maskMatcher.Match(inputLine);
                if (maskMatch.Success)
                {
                    mask = maskMatch.Groups["mask"].Value;
                    continue;
                }

                var memMatch = memMatcher.Match(inputLine);
                if (memMatch.Success)
                {
                    var memIndex     = ulong.Parse(memMatch.Groups["memIndex"].Value);
                    var value        = ulong.Parse(memMatch.Groups["value"].Value);
                    var reversedMask = mask.ToCharArray().Reverse().ToArray();
                    for (int i = 0; i < mask.Length; i++)
                    {
                        value = reversedMask[i] switch
                        {
                            '0' => value &= ~(1UL << i),
                            '1' => value |= 1UL << i,
                                _ => value,
                        };
                    }

                    mem[memIndex] = value;
                }
            }

            console.Output.WriteLine($"{mem.Aggregate((prev, next) => prev + next)}");
            return(default);
コード例 #11
0
        public override string Solve()
        {
            // Compute generating function: Gk = Gk-1 + Gk-2 with G1 = 1 and G2 = 4     http://en.wikipedia.org/wiki/Fibonacci_number#Power_series
            // s(x) = SUM(1,Gk * x^k)  k is SUM index and goes to infinity
            // s(x) = G1 * x + G2 * x^2 + SUM(3,Gk * x^k)
            // s(x) = G1 * x + G2 * x^2 + SUM(3, (Gk-1 + Gk-2) * x^k
            // with G1 = 1 and G2 = 4
            // s(x) = x + 4 * x^2 + SUM(3, (Gk-1 + Gk-2) * x^k)   split sum in 2 sums
            // s(x) = x + 4 * x^2 + SUM(3, Gk-1 * x^k) + SUM(3, Gk-2 * x^k)   extract x and x^2 from sums
            // s(x) = x + 4 * x^2 + x * SUM(3, Gk-1 * x^k-1) + x^2 * SUM(3, Gk-2 * x^k-2)   replace k-1 with k in first sum and k-2 with k in second sum (allowed because sum goes to infinity)
            // s(x) = x + 4 * x^2 + x * SUM(2, Gk * x^k) + x^2 * SUM(1, Gk * x^k)   last sum is s(x) and first sum is s(x) - G1 * x and G1 = 1
            // s(x) = x + 4 * x^2 + x * (s(x) - x) + x^2 * s(x)
            //        x + 3 * x^2
            // s(x) = -----------
            //        1 - x - x^2
            //
            // let n be an integer solution
            // n = (x + 3*x^2)/(1-x-x^2)
            // (3+n) * x^2 + (1+n) * x - n = 0
            // delta = (1+n)^2 + 4*(3+n)*n = 5*n^2 + 14*n + 1  must be a perfect square

            // Brute-Force to find first value
            //List<ulong> nuggets = new List<ulong>();
            //for (ulong i = 1; i < 100000000; i++)
            //{
            //    ulong delta = 5 * i * i + 14 * i + 1;
            //    if (Tools.Tools.IsPerfectSquare(delta))
            //    {
            //        Console.WriteLine(i + "-->" + delta);
            //        nuggets.Add(i);
            //    }
            //}

            // search relation between nugget and fibonacci

            // F
            // 0, 1, 2, 3, 4, 5, 6,  7,  8,  9, 10, 11,  12,  13,  14,  15,  16,   17,   18,   19,   20
            // 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765,

            // N
            // 0, 1,  2,  3,   4,   5,    6,    7,    8,     9,    10,    11,     12,     13,      14,      15,       16,       17
            // 2, 5, 21, 42, 152, 296, 1050, 2037, 7205, 13970, 49392, 95760, 338546, 656357, 2320437, 4498746, 15904520, 30834872

            // nugget(1) - nugget(0) = 5-2 = 3 = F(4)
            // nugget(2) - nugget(1) = 21-5 = 16 = 2*F(6)
            // nugget(3) - nugget(2) = 42-21 = 21 = F(8)
            // nugget(4) - nugget(3) = 152-42 = 110 = 2*F(10)
            // nugget(5) - nugget(4) = 296-152 = 144 = F(12)
            // nugget(6) - nugget(5) = 1050-296 = 754 = 2*F(14)
            // nugget(7) - nugget(6) = 2037-1050 = 987 = F(16)

            // n odd: nugget(n+1) - nugget(n) = F( 2*(n+2) )
            // n even: nugget(n+1) - nugget(n) = 2*F( 2*(n+2) )

            // n odd: nugget(n) = nugget(n-1) + F( 2*(n+1) )
            // n even: nugget(n) = nugget(n-1) + 2*F( 2*(n+1) )

            const int limit = 30;

            ulong[] fibonacci = new ulong[2 * (limit + 1)];
            fibonacci[0] = 0;
            fibonacci[1] = 1;
            for (int i = 2; i < fibonacci.Length; i++)
            {
                fibonacci[i] = fibonacci[i - 1] + fibonacci[i - 2];
            }

            ulong[] nuggets = new ulong[limit];
            nuggets[0] = 2;
            nuggets[1] = 5;
            for (int i = 2; i < limit; i++)
            {
                if (i % 2 != 0)
                {
                    nuggets[i] = nuggets[i - 1] + fibonacci[2 * (i + 1)];
                }
                else
                {
                    nuggets[i] = nuggets[i - 1] + 2 * fibonacci[2 * (i + 1)];
                }
            }

            return(nuggets.Aggregate((ulong)0, (n, i) => n + i).ToString(CultureInfo.InvariantCulture));


            // d^2 = 5*n^2 + 14*n + 1 -> diophantine equation http://www.alpertron.com.ar/QUAD.HTM
            // solutions: { 0, -1 }, { 0, 1 }, { -3, -2 }, { -3, 2 }, { -4, -5 }, { -4, 5 }, { 2, -7 }, { 2, 7 }
            // generators:
            //  n[k+1] = -9 * n[k] - 4 * d[k] - 14
            //  d[k+1] = -20 * n[k] - 9 * d[k] - 28

            //List<Tuple<long, long>> start = new List<Tuple<long, long>>
            //    {
            //        new Tuple<long, long>(0, -1),
            //        new Tuple<long, long>(0, 1),
            //        new Tuple<long, long>(-3, -2),
            //        new Tuple<long, long>(-3, 2),
            //        new Tuple<long, long>(-4, -5),
            //        new Tuple<long, long>(-4, 5),
            //        new Tuple<long, long>(2, -7),
            //        new Tuple<long, long>(2, 7)
            //    };
            //List<ulong> nuggets = new List<ulong>();

            //foreach (Tuple<long, long> couple in start)
            //{
            //    long n = couple.Item1;
            //    long d = couple.Item2;

            //    for (int i = 0; i < 30; i++)
            //    {
            //        long nNew = -9*n - 4*d - 14;
            //        long dNew = -20*n - 9*d - 28;

            //        n = nNew;
            //        d = dNew;

            //        ulong unsignedN = (ulong) n;

            //        if (n > 0 && !nuggets.Contains(unsignedN))
            //            nuggets.Add(unsignedN);
            //    }
            //}

            //return nuggets.OrderBy(x => x).Take(30).Aggregate((ulong) 0, (n, i) => n + i);
        }
コード例 #12
0
ファイル: Problem303.cs プロジェクト: SinaC/ProjectEuler
        public override string Solve()
        {
            // TODO:
            //ull solve(int x)
            //{
            //    static int found[10010];
            //    memset(found, 0, sizeof(found));
            //    if (x < 3) return 1;
            //    queue<pair<ull, int> > q;
            //    q.push(make_pair(ull(1), 1));
            //    q.push(make_pair(ull(2), 2));
            //    found[1] = found[2] = 1;
            //    while (1) {
            //        ull n = q.front().first;
            //        int m = q.front().second;
            //        q.pop();
            //        if (m == 0) return n/x;
            //        for (int i = 0; i <= 2; i++) {
            //            int nm = (m * 10 + i) % x;
            //            if (!found[nm]) {
            //                found[nm] = 1;
            //                q.push(make_pair(n * 10 + (ull) i, nm));
            //            }
            //        }
            //    }
            //}

            //int main(void)
            //{
            //    int bases[2] = { 100, 10000 };
            //    for (int ti = 0; ti < 2; ti++) {
            //        ull r = 0;
            //        for (int i = 1; i <= bases[ti]; i++) r += solve(i);
            //        cout << "Up to " << bases[ti] << ": " << r << endl;
            //    }
            //    return 0;
            //}


            //// Brute-force
            //ulong limit = 10000;
            //ulong sum = 0;
            //for (ulong n = 1; n <= limit; n++) {
            //    ulong multiplier = 0;
            //    switch (n) {
            //        case 9: multiplier = 1358; break; // fn = 12222
            //        case 99: multiplier = 11335578; break; // fn = 1122222222
            //        case 495: multiplier = 22671156; break; // fn = 11222222220
            //        case 990: multiplier = 11335578; break; // fn = 11222222220
            //        case 999: multiplier = 1113335555778; break; // fn = 1112222220222222
            //        case 4995: multiplier = 2226671111556; break; // fn = 11122222202222220
            //        case 9990: multiplier = 1113335555778; break; // fn = 11122222202222220
            //        case 9999: multiplier = 1111333355555557778; break; // fn = 11112222222200022222222
            //        default: multiplier = 0; break;
            //    }
            //    if ( 0 == multiplier ) {
            //        // Compute f(n)
            //        multiplier = 1;
            //        ulong fn = n * multiplier;
            //        while (true) {
            //            bool fOk = true;
            //            ulong test = fn;
            //            while (test > 0) {
            //                ulong digit = test % 10;
            //                if (digit > 2) {
            //                    fOk = false;
            //                    break;
            //                }
            //                test /= 10;
            //            }
            //            if (fOk)
            //                break;
            //            fn += n; // next multiplier
            //            multiplier++;
            //        }
            //    }
            //    sum += multiplier;
            //    list.Add(multiplier);
            //}

            // 2^64-1 -> 10^19
            // Optimisation 1
            //  n * multiplier = fn
            //  n * 10 * multiplier = fn * 10  (fn * 10 will be written with only of 0, 1, 2)
            //  result[n*10] = multiplier
            // Optimisation 2 only if 2*n < limit
            //  for each divisor d of multiplier
            //      n * d * multiplier / d = fn
            //      result[n*d] = multiplier/d

            const ulong limit = 10000;

            ulong[] multiplierList = new ulong[limit + 1];
            // Generate numbers in base-3 (sorted)
            const ulong  digitCount = 15;
            List <ulong> base3List  = new List <ulong>();

            GenerateBase3Numbers(digitCount, 0, base3List); // Arbitrary limit
            base3List.RemoveAt(0);                          // Remove 0
            bool[] sieve = Tools.Tools.BuildSieve(limit);   // Arbitrary limit
            //ulong count = 0;
            multiplierList[0] = 0;
            // Compute Fn
            for (ulong n = 1; n <= limit; n++)
            {
                if (0 != multiplierList[n])
                {
                    continue;
                }
                //count++;
                ulong multiplier;
                switch (n)
                {
                case 9: multiplier = 1358; break;       // fn = 12222

                case 99: multiplier = 11335578; break;  // fn = 1122222222

                case 495: multiplier = 22671156; break; // fn = 11222222220

                //case 990: multiplier = 11335578; break; // fn = 11222222220
                case 999: multiplier = 111333555778; break;     // fn = 111222222222222

                case 4995: multiplier = 222667111556; break;    // fn = 1112222222222220

                //case 9990: multiplier = 111333555778; break; // fn = 1112222222222220
                case 9999: multiplier = 1111333355557778; break;     // fn = 11112222222222222222

                default: multiplier = 0; break;
                }
                // Search if n is a divisor of an item in base-3 list
                foreach (ulong fn in base3List)
                {
                    if (fn >= n)
                    {
                        ulong mod = fn % n;
                        if (0 == mod)
                        {
                            multiplier = fn / n;
                            break;
                        }
                    }
                }

                if (0 == multiplier)
                {
                    //// Not found in list, find it manually
                    //// first multiplier to test must be 10^digitCount / n
                    //// because 10^digitCount is the next base-3
                    //multiplier = Pow(10, digitCount) / n;
                    //ulong fn = n * multiplier;
                    //while (true) {
                    //    bool fOk = true;
                    //    ulong test = fn;
                    //    while (test > 0) {
                    //        ulong digit = test % 10;
                    //        if (digit > 2) {
                    //            fOk = false;
                    //            break;
                    //        }
                    //        test /= 10;
                    //    }
                    //    if (fOk)
                    //        break;
                    //    fn += n; // next multiplier
                    //    multiplier++;
                    //}
                    List <ulong> queue = new List <ulong>
                    {
                        1,
                        2
                    };
                    while (true)
                    {
                        ulong fn = queue[0]; queue.RemoveAt(0);
                        if (fn >= n && 0 == (fn % n))
                        {
                            multiplier = fn / n;
                            break;
                        }
                        for (ulong i = 0; i <= 2; i++)
                        {
                            queue.Add(10 * fn + i);
                        }
                    }
                }
                multiplierList[n] = multiplier;
                // Optimisation 1
                ulong mul10 = n;
                while (true)
                {
                    mul10 *= 10;
                    if (mul10 > limit)
                    {
                        break;
                    }
                    multiplierList[mul10] = multiplier;
                }
                // Optimisation 2
                if (multiplier > 3 && 2 * n < limit)
                {
                    //ulong sqrtMultipler = (ulong)(Math.Sqrt(multiplier) + 0.5);
                    ulong p = 2;
                    while (true)
                    {
                        ulong test = multiplier;
                        ulong newN = n;
                        if (newN * p > limit) // stops if limit is reached
                        {
                            break;
                        }
                        while (test != p && 0 == (test % p))
                        {
                            test /= p;
                            newN *= p;
                            if (newN > limit) // stops if limit is reached
                            {
                                break;
                            }
                            multiplierList[newN] = test;
                        }
                        if (2 == p)
                        {
                            p++;
                        }
                        else
                        {
                            p += 2;
                        }
                        while (p <= limit && sieve[p])
                        {
                            p += 2;
                        }
                        if (p > limit)
                        {
                            break;
                        }
                    }
                }
            }
            //// DEBUG
            //using (System.IO.StreamWriter sw = new System.IO.StreamWriter(@"..\..\..\output.txt")) {
            //    for (ulong n = 1; n <= limit; n++) {
            //        ulong multiplier = multiplierList[n];
            //        if (multiplier == 0) {
            //            sw.WriteLine(n + "  !!!!!!!!!!!!!!!!NOT FOUND!!!!!!!!!!!!!");
            //        }
            //        else {
            //            ulong fn = n * multiplier;
            //            sw.WriteLine(n + " * " + multiplier + " = " + fn);
            //        }
            //    }
            //    sw.WriteLine("Sum=" + sum);
            //}
            return(multiplierList.Aggregate <ulong, ulong>(0, (current, multiplier) => current + multiplier).ToString(CultureInfo.InvariantCulture));
        }
コード例 #13
0
ファイル: Problem153.cs プロジェクト: SinaC/ProjectEuler
        public ulong Solve3()
        {
            const ulong limit = 16;

            ulong[] count = new ulong[limit + 1];

            // special case for 1
            count[1] = 1;
            // divisible by 1 and n
            for (ulong i = 2; i <= limit; i++)
            {
                count[i] += i + 1;
            }
            // if a == b, every multiple of 2*a are divisible a+ai and a-ai
            for (ulong i = 1; i <= limit / 2; i++)
            {
                Console.Write("{0}+{0}i and {0}-{0}i divides: ", i);
                for (ulong j = 2 * i; j < limit; j += 2 * i)
                {
                    Console.Write("{0},", j);
                    count[j] += 2 * i;
                }
                Console.WriteLine();
            }
            // every multiple of i
            for (ulong i = 2; i <= limit / 2; i++)
            {
                Console.Write("multiple of {0}: ", i);
                for (ulong j = i + i; j < limit; j += i)
                {
                    Console.Write("{0},", j);
                    count[j] += i;
                }
                Console.WriteLine();
            }

            ulong sqrtLimit = (ulong)Math.Sqrt(limit / 2) + 1;

            for (ulong a = 1; a <= sqrtLimit; a++)
            {
                for (ulong b = a + 1; ; b++) // a and b are interchangeable
                {
                    Console.WriteLine("testing {0},{1}", a, b);
                    ulong c = 2 * a + 2 * b; // a+bi+a-bi+b+ai+b-ai
                    ulong s = a * a + b * b;
                    if (s > limit)
                    {
                        Console.WriteLine("{0} breaking limit", s);
                        break;
                    }
                    for (ulong i = 1; i <= limit / s; i++)
                    {
                        // every multiple
                        count[i * s] += c * i;
                        Console.WriteLine("\t{0} is divisible {1}", i * s, c * i);
                    }
                }
            }

            ulong sum = count.Aggregate((ulong)0, (n, i) => n + i);

            ////ulong sum = count.Select((n, i) => i == 0 ? 0 : (limit/(ulong) i)*((ulong) i + n)).Aggregate((ulong) 0, (n, i) => n + i);
            //var x = count.Select((n, i) => i == 0 ? 0 : (limit/(ulong) i)*((ulong) i + n));
            //ulong sum = x.Aggregate((ulong)0, (n, i) => n + i);
            return(sum);
        }