উইথফ ম্যাট্রিক্স মডুলো 2 এ একটি নির্দিষ্ট মান মুদ্রণ করুন


11

উইথফ ম্যাট্রিক্স একটি অসীম ম্যাট্রিক্স যা উইথফের গেমের দাবাবোর্ডে প্রতিটি স্কয়ারের গ্রান্দি সংখ্যার সমন্বয়ে গঠিত

এই ম্যাট্রিক্সের প্রতিটি এন্ট্রি ক্ষুদ্রতম nonnegative সংখ্যার সমান যা উপরের, বামে বা প্রবেশের অবস্থানের ত্রিভুজ উত্তর-পশ্চিমে প্রদর্শিত হয় না।

উপরের বামে 20-বাই-20 স্কোয়ারটি দেখতে এমন দেখাচ্ছে

  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19
  1  2  0  4  5  3  7  8  6 10 11  9 13 14 12 16 17 15 19 20
  2  0  1  5  3  4  8  6  7 11  9 10 14 12 13 17 15 16 20 18
  3  4  5  6  2  0  1  9 10 12  8  7 15 11 16 18 14 13 21 17
  4  5  3  2  7  6  9  0  1  8 13 12 11 16 15 10 19 18 17 14
  5  3  4  0  6  8 10  1  2  7 12 14  9 15 17 13 18 11 16 21
  6  7  8  1  9 10  3  4  5 13  0  2 16 17 18 12 20 14 15 11
  7  8  6  9  0  1  4  5  3 14 15 13 17  2 10 19 21 12 22 16
  8  6  7 10  1  2  5  3  4 15 16 17 18  0  9 14 12 19 23 24
  9 10 11 12  8  7 13 14 15 16 17  6 19  5  1  0  2  3  4 22
 10 11  9  8 13 12  0 15 16 17 14 18  7  6  2  3  1  4  5 23
 11  9 10  7 12 14  2 13 17  6 18 15  8 19 20 21  4  5  0  1
 12 13 14 15 11  9 16 17 18 19  7  8 10 20 21 22  6 23  3  5
 13 14 12 11 16 15 17  2  0  5  6 19 20  9  7  8 10 22 24  4
 14 12 13 16 15 17 18 10  9  1  2 20 21  7 11 23 22  8 25 26
 15 16 17 18 10 13 12 19 14  0  3 21 22  8 23 20  9 24  7 27
 16 17 15 14 19 18 20 21 12  2  1  4  6 10 22  9 13 25 11 28
 17 15 16 13 18 11 14 12 19  3  4  5 23 22  8 24 25 21 26 10
 18 19 20 21 17 16 15 22 23  4  5  0  3 24 25  7 11 26 12 13
 19 20 18 17 14 21 11 16 24 22 23  1  5  4 26 27 28 10 13 25

উইথফ ম্যাট্রিক্সে একটি স্বেচ্ছাসেবী প্রবেশের গণনা করার জন্য বর্তমানে কোনও কার্যকর অ্যালগরিদম নেই। যাইহোক, এই সমস্যাটিতে আপনার কাজটি হিউরিস্টিক ফাংশনটি ডিজাইন করার চেষ্টা করা যা কোনও নির্দিষ্ট স্থানাঙ্কের সংখ্যাটি কিনা তা জানায়wythoff(x, y) সমান বা বিজোড় ।

আপনার প্রোগ্রামে সোর্স কোড KB৪ কেবি (, 65,৫36 more বাইট) এর বেশি নাও থাকতে পারে, বা ২ এমবি (২,০৯7,১৫২ বাইট) বেশি ওয়ার্কিং মেমরি ব্যবহার করতে পারে না।

বিশেষত মেমোরি ব্যবহারের জন্য, এর অর্থ হ'ল আপনার প্রোগ্রামের সর্বাধিক আবাসিক সেট আকার সেই ভাষাতে খালি প্রোগ্রামের সর্বাধিক আবাসিক সেট আকারের চেয়ে 2 এমবি অতিক্রম করতে পারে না। কোনও অনুবাদিত ভাষার ক্ষেত্রে এটি নিজেই দোভাষী / ভার্চুয়াল মেশিনের মেমরি ব্যবহার এবং সংকলিত ভাষার ক্ষেত্রে এটি এমন একটি প্রোগ্রামের মেমরি ব্যবহার যা মূল পদ্ধতিটি কার্যকর করে এবং কিছুই করে না।

আপনার প্রোগ্রামটি 10000 x 10000সারির মানগুলিতে 20000 <= x <= 29999এবং কলামের মানগুলির জন্য ম্যাট্রিক্সে পরীক্ষা করা হবে 20000 <= y <= 29999

আপনার প্রোগ্রামের স্কোর হ'ল সংক্ষিপ্ত কোডটি টাইব্রেকার হিসাবে অভিনয় করে আপনার প্রোগ্রামটি যথাযথতা হার (সঠিক অনুমানের সংখ্যা) অর্জন করে।


3
01.Rএমন একটি 05AB1E যা এলোমেলোভাবে সত্য বা মিথ্যা আউটপুট করে। 0 টি সত্য হতে দিন এবং 1 টি মিথ্যা হোক, আমার প্রোগ্রামটি তাত্ত্বিকভাবে সময়টির সঠিক% 50% হবে। এটি কি বৈধ এন্ট্রি?
ম্যাজিক অক্টোপাস উরন

@ কারাসোকম্পিউটিং আসলে, আমি উল্লেখ করতে ভুলে গেছি যে এলোমেলো সমাধানগুলি অনুমোদিত নয় - আপনার প্রোগ্রামটি প্রতিবার একই ইনপুটটির জন্য একই আউটপুট তৈরি করা উচিত, যদিও আমি সন্দেহ করি যে শব্দটি ফাংশনটি বোঝায়।
জো জেড।

আমি যদি প্রতিটি কলটিতে আমার প্রঙের বীজ ঠিক করি তবে এটি অভিন্ন ইনপুটটির জন্য একই আউটপুট তৈরি করবে এবং আমি আপনাকে কী বলতে চাই তা জানি তবে আপনি সম্ভবত এটি আরও নির্দিষ্টভাবে বলতে হবে word
মাইল


@ লিনাস কি "উইথফসের গেম ম্যাট্রিক্স" আরও ভাল হবে? আমি পৃষ্ঠাটিও দেখেছি।
জো জেড।

উত্তর:


6

পাইথন; নির্ভুলতা = 54,074,818; আকার = 65,526 বাইট

পূর্ববর্তী স্কোর: 50,227,165; 50.803.687; 50.953.001

#coding=utf-8
d=r'''<65,400 byte string>'''
def f(x,y):
 a=max(x,y)-20000;b=min(x,y)-20000;c=(a*(a+1)//2+b)%523200
 return(ord(d[c//8])>>(c%8))&1

এই পদ্ধতিটি ম্যাট্রিক্সের সমস্ত অনন্য এন্ট্রিগুলিকে 523,200 গ্রুপে বিভক্ত করে এবং বাইনারি স্ট্রিং থেকে গ্রুপের (x, y) সেরা অনুমানটি পড়ে । আপনি গুগল ড্রাইভ থেকে সম্পূর্ণ উত্স কোডটি ডাউনলোড করতে পারেন ।

আমি স্ট্রিং উত্পন্ন করতে এবং যথার্থতা গণনা করতে @ পিটারটেলারের পার্টিশন ব্যবহার করেছি ।


আমি অনেক ভিন্ন, আরও আকর্ষণীয় পদ্ধতির চেষ্টা করেছি, কিন্তু শেষ পর্যন্ত, একটি সাধারণ হার্ডকোড তাদের সকলকে আউটস্কোর করেছিল ...
ডেনিস

হার্ডকোডিংও একটি বৈধ পন্থা - এটি রূপান্তরিত হতে পারে, বলে, যা হার্ডকোডিং স্কিম সেরা ফলাফল দেয়।
জো জেড।

অন্যথায় বলছি না, তবে যেহেতু প্যারিটিগুলি বিতরণ করা খুব স্পষ্টতই এলোমেলো, তাই আমি এই পদ্ধতির আউটসোর্স করার আশা করছিলাম। এখনও পর্যন্ত, আমার সমস্ত প্রচেষ্টা ব্যর্থ হয়েছে যদিও।
ডেনিস

নাহ, ঠিক আছে। এর অর্থ হ'ল এই সমস্যাটি সঠিকভাবে করা খুব কঠিন। আমি এক ধরণের মাত্রিক ব্যতীত এই শৈলীর আরও একগুচ্ছ সমস্যা তৈরি করছি। আপনি যদি এগুলি পরীক্ষা করে দেখতে চান তবে এগুলি সমস্তই স্যান্ডবক্সে রয়েছে।
জো জেড।

4

সিজেএম (নির্ভুলতা 50016828/100000000, 6 বাইট)

{+1&!}

(অ-সিজ্যামারদের জন্য ALGOL- রীতিতে সিউডোকোডে: return ((x + y) & 1) == 0 :)।

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


স্কোর ধরে নিয়েছে যে ম্যাট্রিক্সের আমার গণিত বিভাগটি সঠিক is স্বতন্ত্র যাচাই স্বাগত। আমি গণনা করা প্যারিটি বিটগুলি http://cheddarmonk.org/codegolf/PPCG95604-parity.bz2 এ হোস্ট করছি (8MB ডাউনলোড, 50MB টেক্সট ফাইল থেকে এক্সট্রাক্ট) : যেহেতু ম্যাট্রিক্স মূল তির্যকটি সম্পর্কে প্রতিসম, তাই আমি কেবল প্রতিটি অন্তর্ভুক্ত করেছি মূল তির্যকটি থেকে শুরু করে লাইন, সুতরাং আপনাকে অফসেট করতে হবে, স্থানান্তর করতে হবে, এবং বিটওয়াইস করতে হবে বা পুরো বর্গক্ষেত্র পেতে))

আমি কোডটি এটি গণনা করতে ব্যবহার করি তা জাভা। এটি সংজ্ঞাটি মোটামুটি সোজাসাপ্টাভাবে ব্যবহার করে, তবে একটি সেট ডেটা স্ট্রাকচারের সাহায্যে রান-লেংথ রেঞ্জগুলি এনকোড করে দেয় যাতে এটি পরবর্তী অনুমতি প্রাপ্ত মানটিতে দ্রুত যেতে পারে। আরও অপ্টিমাইজেশন সম্ভব হবে, তবে এটি আমার মাঝারি মানের ডেস্কটপে প্রায় দুই ঘন্টা এবং 1.5 জিবি হিপ স্পেসে চলে।

import java.util.*;

public class PPCG95604Analysis
{
    static final int N = 30000;

    public static void main(String[] args) {
        Indicator[] cols = new Indicator[N];
        Indicator[] diag = new Indicator[N];
        for (int i = 0; i < N; i++) {
            cols[i] = new Indicator();
            diag[i] = new Indicator();
        }

        int maxVal = 0;

        for (int y = 0; y < N; y++) {
            Indicator row = new Indicator(cols[y]);

            for (int x = y; x < N; x++) {
                Indicator col = cols[x];
                Indicator dia = diag[x - y];

                Indicator.Result rr = row.firstCandidate();
                Indicator.Result rc = col.firstCandidate();
                Indicator.Result rd = dia.firstCandidate();

                while (true) {
                    int max = Math.max(Math.max(rr.candidateValue(), rc.candidateValue()), rd.candidateValue());
                    if (rr.candidateValue() == max && rc.candidateValue() == max && rd.candidateValue() == max) break;

                    if (rr.candidateValue() != max) rr = rr.firstCandidateGreaterThan(max - 1);
                    if (rc.candidateValue() != max) rc = rc.firstCandidateGreaterThan(max - 1);
                    if (rd.candidateValue() != max) rd = rd.firstCandidateGreaterThan(max - 1);
                }

                if (y >= 20000 && x >= 20000) System.out.format("%d", rr.candidateValue() & 1);
                maxVal = Math.max(maxVal, rr.candidateValue());
                rr.markUsed();
                rc.markUsed();
                rd.markUsed();
            }
            if (y >= 20000) System.out.println();
        }
    }

    static class Indicator
    {
        private final int INFINITY = (short)0xffff;
        private final int MEMBOUND = 10000;

        private short[] runLengths = new short[MEMBOUND];

        public Indicator() { runLengths[1] = INFINITY; }

        public Indicator(Indicator clone) { System.arraycopy(clone.runLengths, 0, runLengths, 0, MEMBOUND); }

        public Result firstCandidate() {
            // We have a run of used values, followed by a run of unused ones.
            return new Result(1, 0xffff & runLengths[0], 0xffff & runLengths[0]);
        }

        class Result
        {
            private final int runIdx;
            private final int runStart;
            private final int candidateValue;

            Result(int runIdx, int runStart, int candidateValue) {
                this.runIdx = runIdx;
                this.runStart = runStart;
                this.candidateValue = candidateValue;
            }

            public int candidateValue() {
                return candidateValue;
            }

            public Result firstCandidateGreaterThan(int x) {
                if (x < candidateValue) throw new IndexOutOfBoundsException();

                int idx = runIdx;
                int start = runStart;
                while (true) {
                    int end = start + (0xffff & runLengths[idx]) - 1;
                    if (end > x) return new Result(idx, start, x + 1);

                    // Run of excluded
                    start += 0xffff & runLengths[idx];
                    idx++;
                    // Run of included
                    start += 0xffff & runLengths[idx];
                    idx++;

                    if (start > x) return new Result(idx, start, start);
                }
            }

            public void markUsed() {
                if (candidateValue == runStart) {
                    // Transfer one from the start of the run to the previous run
                    runLengths[runIdx - 1]++;
                    if (runLengths[runIdx] != INFINITY) runLengths[runIdx]--;
                    // May need to merge runs
                    if (runLengths[runIdx] == 0) {
                        runLengths[runIdx - 1] += runLengths[runIdx + 1];
                        for (int idx = runIdx; idx < MEMBOUND - 2; idx++) {
                            runLengths[idx] = runLengths[idx + 2];
                            if (runLengths[idx] == INFINITY) break;
                        }
                    }

                    return;
                }

                if (candidateValue == runStart + (0xffff & runLengths[runIdx]) - 1) {
                    // Transfer one from the end of the run to the following run.
                    if (runLengths[runIdx + 1] != INFINITY) runLengths[runIdx + 1]++;
                    if (runLengths[runIdx] != INFINITY) runLengths[runIdx]--;
                    // We never need to merge runs, because if we did we'd have hit the previous case instead
                    return;
                }

                // Need to split the run. From
                //   runIdx: a+1+b
                // to
                //   runIdx: a
                //   runIdx+1: 1
                //   runIdx+2: b
                //   runIdx+3: previous val at runIdx+1
                for (int idx = MEMBOUND - 1; idx > runIdx + 2; idx--) {
                    runLengths[idx] = runLengths[idx - 2];
                }
                runLengths[runIdx + 2] = runLengths[runIdx] == INFINITY ? INFINITY : (short)((0xffff & runLengths[runIdx]) + runStart - 1 - candidateValue);
                runLengths[runIdx + 1] = 1;
                runLengths[runIdx] = (short)(candidateValue - runStart);
            }
        }
    }
}

3

জে, নির্ভুলতা = 50022668/10 8 = 50.0227%, 4 বাইট

2|*.

স্থানাঙ্ক দুটি আর্গুমেন্ট হিসাবে গ্রহণ করে, তাদের মধ্যে LCM গণনা করে এবং এটি মডুলো গ্রহণ করে 2 এর 0অর্থ এটি সমান এবং একটি1 উপায়ে এটা বিজোড় হয়।

পারফরম্যান্স @ পিটার টেলর সরবরাহ করেছেন প্যারিটি বিটের উপর ভিত্তি করে

7 টি বাইটের আগে পিআরএনজি সংস্করণে 2|?.@#.50010491/10 8 এর যথার্থতা ছিল

ব্যাখ্যা

2|*.  Input: x on LHS, y on RHS
  *.  LCM(x, y)
2|    Modulo 2

1
এলসিএমের সমতা হ'ল বিটওয়াইস এবং এন্ডের সমতা। এটি কি আপনাকে একটি বাইট বাঁচায়? আকর্ষণীয় বিষয়টি হ'ল এটি খুব স্পষ্টতই একটি খারাপ হিউরিস্টিক (এটি সময়টির 1মাত্র 25% সময় দেয়, যখন সঠিক অনুপাতটি প্রায় 50% হয়), এবং এখনও এটি এমন অনেকের চেয়ে ভাল করে তোলে যা স্পষ্টত খারাপ নয়।
পিটার টেলর

ধন্যবাদ, তবে দুর্ভাগ্যক্রমে বিটওয়্যার এবং জে আক্ষরিক অর্থে AND
মাইল

@ পিটারটেলর এই ধরণের বিস্ময়কর হিউরিস্টিক আবিষ্কারটি হ'ল এই জাতীয় চ্যালেঞ্জগুলি সম্পর্কে ধারণা করা উচিত।
জো জেড।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.