অনুমানক যেমন কোনও কে + ২ পয়েন্ট ডিগ্রি কে-এর কোনও বহুবর্ষে পড়ে না


16

বিবরণ

যদি বিন্দুগুলির কোনও সেট (তাদের সূচকগুলি সহ) কোনও ডিগ্রির বহুবর্ষে না পড়ে তবে পূর্ণসংখ্যার এক ক্রমকে নূন্যতম আন্তঃপ্রবিষ্ট{1, 2, ..., n} বলা যায় । এটাই,k+2k

  1. কোনও দুটি পয়েন্ট একটি অনুভূমিক রেখায় পড়ে না (0-ডিগ্রি বহুবচন)
  2. কোন লাইনে তিন পয়েন্ট পড়ে না (1-ডিগ্রি বহুবচন)
  3. কোনও পয়েন্ট প্যারাবোলায় পড়ে না (২-ডিগ্রি বহুপ্রথম)
  4. ইত্যাদি।

চ্যালেঞ্জ

OEIS ক্রম A301802 (n) কে গণনা করে এমন একটি প্রোগ্রাম লিখুন , যতটা সম্ভব বৃহত্তর {1, 2, ..., n}জন্য স্বল্পতম অন্তর বিভাজক ক্রমের সংখ্যা n


স্কোরিং

আমি আপনার কোডটি আমার কম্পিউটারে (২.৩ গিগাহার্টজ ইন্টেল কোর আই ৫, ৮ গিগাবাইট র‌্যাম) বাড়িয়ে ইনপুট দিয়ে সময় করব। আপনার স্কোরটি সর্বাধিক ইনপুট হবে যা সঠিক মান আউটপুট করতে 1 মিনিটেরও কম সময় নেয়।


উদাহরণ

উদাহরণস্বরূপ, অনুচ্ছেদটি [1, 2, 4, 3]ন্যূনতম আন্তঃপ্রবিযুক্ত কারণ এটি

the terms together with their indices 
[(1, 1), (2, 2), (3, 4), (4, 3)] 
have the property that
  (0) No two points have the same y-value.
  (1) No three points lie on a line.
  (2) No four points lie on a parabola.

উদাহরণস্বরূপ উদাহরণস্বরূপ যে [1,2,4,3] নূন্যতম অন্তরঙ্গীয়। চিত্রণে, আপনি দেখতে পাচ্ছেন যে অনুভূমিক রেখাগুলি (লাল) তাদের উপরের এক বিন্দুতে রয়েছে, রেখাগুলি (নীল) তাদের উপর দুটি পয়েন্ট থাকে এবং প্যারোব্লাস (সবুজ) তাদের তিনটি পয়েন্ট থাকে।


উপাত্ত

এখানে ন্যূনতমরূপে interpolable একাধিক বিন্যাসন জন্য n=3, n=4এবং n=5:

n = 3: [1,3,2],[2,1,3],[2,3,1],[3,1,2]
n = 4: [1,2,4,3],[1,3,2,4],[1,3,4,2],[1,4,2,3],[2,1,3,4],[2,1,4,3],[2,3,1,4],[2,4,1,3],[2,4,3,1],[3,1,2,4],[3,1,4,2],[3,2,4,1],[3,4,1,2],[3,4,2,1],[4,1,3,2],[4,2,1,3],[4,2,3,1],[4,3,1,2]
n = 5: [1,2,5,3,4],[1,3,2,5,4],[1,3,4,2,5],[1,4,2,3,5],[1,4,3,5,2],[1,4,5,2,3],[1,4,5,3,2],[1,5,3,2,4],[2,1,4,3,5],[2,3,1,4,5],[2,3,5,1,4],[2,3,5,4,1],[2,4,1,5,3],[2,4,3,1,5],[2,4,5,1,3],[2,5,1,3,4],[2,5,1,4,3],[2,5,3,4,1],[2,5,4,1,3],[3,1,4,5,2],[3,1,5,2,4],[3,1,5,4,2],[3,2,5,1,4],[3,2,5,4,1],[3,4,1,2,5],[3,4,1,5,2],[3,5,1,2,4],[3,5,1,4,2],[3,5,2,1,4],[4,1,2,5,3],[4,1,3,2,5],[4,1,5,2,3],[4,1,5,3,2],[4,2,1,5,3],[4,2,3,5,1],[4,2,5,1,3],[4,3,1,2,5],[4,3,1,5,2],[4,3,5,2,1],[4,5,2,3,1],[5,1,3,4,2],[5,2,1,3,4],[5,2,1,4,3],[5,2,3,1,4],[5,2,4,3,1],[5,3,2,4,1],[5,3,4,1,2],[5,4,1,3,2]

যদি আমার প্রোগ্রামটি সঠিক হয় তবে এর প্রথম কয়েকটি মান a(n), এর স্বল্পতম আন্তঃব্যক্তিক ক্রয়ের সংখ্যা {1, 2, ..., n}:

a(1) = 1
a(2) = 2
a(3) = 4
a(4) = 18
a(5) = 48
a(6) = 216
a(7) = 584
a(8) = 2870

দুর্দান্ত সিকোয়েন্স নম্বর! | যদিও আপনি দ্রুততম কোড নির্দিষ্ট করেছেন , আপনি কোন মেশিনটি দ্রুততম তা নির্দিষ্ট করে দেননি। জয়ের মানদণ্ডটি আসলে কী?
ব্যবহারকারী 202729

3
ব্যবহারকারী ২২২29২৯ এর মন্তব্যে যুক্ত করতে, আমি কয়েকটি ট্যাগের পরামর্শ দিচ্ছি যা আপনি বিজয়ী মানদণ্ড নির্ধারণ করতে ব্যবহার করতে পারেন: দ্রুততম কোডটির প্রয়োজন রানটাইম তুলনা করার জন্য একই মেশিনে সাবমিশন পরীক্ষা করা উচিত (সাধারণত চ্যালেঞ্জের ওপি এটি করে)। দ্রুততম-অ্যালগরিদম উত্তরদাতাদের যতটা সম্ভব সর্বনিম্ন সময়ের জটিলতার সাথে কোড নিয়ে আসতে বলবে। কোড-গল্ফ ব্যবহারকারীদের যতটা সম্ভব সংক্ষিপ্ততম উত্স কোড (বা সমমানের) সহ কোড নিয়ে আসতে বলবে। তা ছাড়া, এটি অবশ্যই একটি দুর্দান্ত চ্যালেঞ্জ।
জংহওয়ান মিন

আপনার উদাহরণ পাঠ্যটি শূন্য-সূচক ব্যবহার করে যদিও চিত্রটি এক সূচক ব্যবহার করে।
জোনাথন ফ্রেচ

যেহেতু সমস্ত পয়েন্টগুলি প্রথম প্রাকৃতিক সংখ্যার অনুমান দ্বারা সংজ্ঞায়িত হয়, তাই কোনও দুটি পয়েন্টের পক্ষে একই উচ্চতা দখল করা কি অসম্ভব নয়?
জোনাথন ফ্রেচ

@ জোনাথনফ্রেচ, প্রকৃতপক্ষে, এটি 1-সূচিযুক্ত হওয়া উচিত কারণ এগুলি অনুমোদন। এবং আপনি সঠিক! যেহেতু আমরা ক্রমশক্তি নিয়ে কাজ করছি, 0 ডিগ্রি বহুপদী শর্তটি নিখরচায় আসে।
পিটার কেজে

উত্তর:


5

সি শার্প

using System;
using System.Diagnostics;
using BigInteger = System.Int32;

namespace Sandbox
{
    class PPCG160382
    {
        public static void Main(params string[] args)
        {
            if (args.Length != 0)
            {
                foreach (var arg in args) Console.WriteLine(CountValidPerms(int.Parse(arg)));
            }
            else
            {
                int[] smallValues = new int[] { 1, 1, 2, 4, 18, 48 };
                for (int n = 0; n < smallValues.Length; n++)
                {
                    var observed = CountValidPerms(n);
                    var expected = smallValues[n];
                    Console.WriteLine(observed == expected ? $"{n}: Ok" : $"{n}: expected {expected}, observed {observed}, error {observed - expected}");
                }
                for (int n = smallValues.Length; n < 13; n++)
                {
                    Stopwatch sw = new Stopwatch();
                    sw.Start();
                    Console.WriteLine($"{n}: {CountValidPerms(n)} in {sw.ElapsedMilliseconds}ms");
                }
            }
        }

        private static long CountValidPerms(int n)
        {
            // We work on the basis of exclusion by extrapolation.
            var unused = (1 << n) - 1;
            var excluded = new int[n];
            int[] perm = new int[n];

            // Symmetry exclusion: perm[0] < (n+1) / 2
            if (n > 1) excluded[0] = (1 << n) - (1 << ((n + 1) / 2));

            long count = 0;
            CountValidPerms(ref count, perm, 0, unused, excluded);
            return count;
        }

        private static void CountValidPerms(ref long count, int[] perm, int off, int unused, int[] excluded)
        {
            int n = perm.Length;
            if (off == n)
            {
                count += CountSymmetries(perm);
                return;
            }

            // Quick-aborts
            var completelyExcluded = excluded[off];
            for (int i = off + 1; i < n; i++)
            {
                if ((unused & ~excluded[i]) == 0) return;
                completelyExcluded &= excluded[i];
            }
            if ((unused & completelyExcluded) != 0) return;

            // Consider each unused non-excluded value as a candidate for perm[off]
            var candidates = unused & ~excluded[off];
            for (int val = 0; candidates > 0; val++, candidates >>= 1)
            {
                if ((candidates & 1) == 0) continue;

                perm[off] = val;

                var nextUnused = unused & ~(1 << val);

                var nextExcluded = (int[])excluded.Clone();
                // For each (non-trivial) subset of smaller indices, combine with off and extrapolate to off+1 ... excluded.Length-1
                if (off < n - 1 && off > 0)
                {
                    var points = new Point[off + 1];
                    var denoms = new BigInteger[off + 1];
                    points[0] = new Point { X = off, Y = perm[off] };
                    denoms[0] = 1;
                    ExtendExclusions(perm, off, 0, points, 1, denoms, nextExcluded);
                }

                // Symmetry exclusion: perm[0] < perm[-1] < n - 1 - perm[0]
                if (off == 0 && n > 1)
                {
                    nextExcluded[n - 1] |= (1 << n) - (2 << (n - 1 - val));
                    nextExcluded[n - 1] |= (2 << val) - 1;
                }

                CountValidPerms(ref count, perm, off + 1, nextUnused, nextExcluded);
            }
        }

        private static void ExtendExclusions(int[] perm, int off, int idx, Point[] points, int numPoints, BigInteger[] denoms, int[] excluded)
        {
            if (idx == off) return;

            // Subsets without
            ExtendExclusions(perm, off, idx + 1, points, numPoints, denoms, excluded);

            // Just add this to the subset
            points[numPoints] = new Point { X = idx, Y = perm[idx] };
            denoms = (BigInteger[])denoms.Clone();
            // Update invariant: denoms[s] = prod_{t != s} points[s].X - points[t].X
            denoms[numPoints] = 1;
            for (int s = 0; s < numPoints; s++)
            {
                denoms[s] *= points[s].X - points[numPoints].X;
                denoms[numPoints] *= points[numPoints].X - points[s].X;
            }
            numPoints++;

            for (int target = off + 1; target < excluded.Length; target++)
            {
                BigInteger prod = 1;
                for (int t = 0; t < numPoints; t++) prod *= target - points[t].X;

                Rational sum = new Rational(0, 1);
                for (int s = 0; s < numPoints; s++) sum += new Rational(prod / (target - points[s].X) * points[s].Y, denoms[s]);

                if (sum.Denom == 1 && sum.Num >= 0 && sum.Num < excluded.Length) excluded[target] |= 1 << (int)sum.Num;
            }

            // Subsets with
            ExtendExclusions(perm, off, idx + 1, points, numPoints, denoms, excluded);
        }

        private static int CountSymmetries(int[] perm)
        {
            if (perm.Length < 2) return 1;

            int cmp = 0;
            for (int i = 0, j = perm.Length - 1; i <= j; i++, j--)
            {
                cmp = perm.Length - 1 - perm[i] - perm[j];
                if (cmp != 0) break;
            }

            return cmp > 0 ? 4 : cmp == 0 ? 2 : 0;
        }

        public struct Point
        {
            public int X;
            public int Y;
        }

        public struct Rational
        {
            public Rational(BigInteger num, BigInteger denom)
            {
                if (denom == 0) throw new ArgumentOutOfRangeException(nameof(denom));

                if (denom < 0) { num = -num; denom = -denom; }

                var g = _Gcd(num, denom);
                Num = num / g;
                Denom = denom / g;
            }

            private static BigInteger _Gcd(BigInteger a, BigInteger b)
            {
                if (a < 0) a = -a;
                if (b < 0) b = -b;
                while (a != 0)
                {
                    var tmp = b % a;
                    b = a;
                    a = tmp;
                }
                return b;
            }

            public BigInteger Num;
            public BigInteger Denom;

            public static Rational operator +(Rational a, Rational b) => new Rational(a.Num * b.Denom + a.Denom * b.Num, a.Denom * b.Denom);
        }
    }
}

nকমান্ড-লাইন আর্গুমেন্ট হিসাবে মান গ্রহণ করে , বা যদি আর্গুমেন্ট ছাড়াই চালিত হয় তবে এটি বার বার হয়ে যায় n=10। ভিএস 2017 এ "রিলিজ" হিসাবে সংকলন এবং একটি ইন্টেল কোর আই 7-6700 এ চলছে আমি n=91.2 সেকেন্ডে এবং n=1013.6 সেকেন্ডে গণনা করি । n=11মাত্র 2 মিনিটের বেশি।

FWIW:

n    a(n)
9    10408
10   45244
11   160248
12   762554
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.