Ejemplo n.º 1
0
 public static Fraction AngleBetween(Pos p1, Pos p2)
 {
     return(new Fraction(p1.Y - p2.Y, p1.X - p2.X));
 }
Ejemplo n.º 2
0
        static void Main(string[] args)
        {
            const int limit = 2500000;

            mpz_t prime      = 2;
            int   totalCount = 0;
            var   peaks      = new Dictionary <int, Pos>()
            {
                [0] = new Pos(0, 0, 0),
                [1] = new Pos(2, 2, 1)
            };
            Stopwatch sw = Stopwatch.StartNew();

            for (int i = 2; i <= limit; i++)
            {
                if (i % 10000 == 0)
                {
                    var velocity = (1000000000d) / sw.ElapsedTicks;
                    Console.Write($"{(double)i / limit:P1}, velocity={velocity:0.00000}\r");
                    sw.Restart();
                }
                var next2Primes = (prime = prime.NextPrimeGMP(), prime = prime.NextPrimeGMP());
                var xpos        = peaks[i - 1].X + next2Primes.Item1 + next2Primes.Item2;
                var ypos        = peaks[i - 1].Y - next2Primes.Item1 + next2Primes.Item2;
                peaks[i] = new Pos(xpos, ypos, i);
            }
            Console.WriteLine("\nMade peaks");

            int lowerLimit = 1;

            peaks[2].IsHull = true;
            for (int i = 2; ; i++)
            {
                Console.WriteLine($"{lowerLimit} - {i}, {(double)i / limit:P1}");
                int      count    = 1;
                Fraction minAngle = Fraction.AngleBetween(peaks[i], peaks[i - 1]);
                for (int j = i - 2; j >= lowerLimit; j--)
                {
                    var angle = Fraction.AngleBetween(peaks[i], peaks[j]);
                    if (angle.CompareTo(minAngle) < 0)
                    {
                        minAngle = angle;
                        count++;
                    }
                }
                totalCount += count;
                if (i == limit)
                {
                    break;
                }
                if (peaks[i].IsHull)
                {
                    var next = peaks.Where(p => p.Key > i)
                               .OrderByDescending(p => Fraction.AngleBetween(p.Value, peaks[i]))
                               .First();
                    next.Value.IsHull = true;
                    lowerLimit        = i;
                }
            }

            Console.WriteLine($"\n{totalCount}");
        }