वायथॉफ मैट्रिक्स मॉडुलो 2 में एक विशिष्ट मूल्य प्रिंट करें


11

वायथॉफ मैट्रिक्स एक अनंत मैट्रिक्स है जिसमें वीथॉफ़ के खेल में एक शतरंज की बिसात पर प्रत्येक वर्ग की ग्रुंडी संख्या होती है ।

इस मैट्रिक्स में प्रत्येक प्रविष्टि सबसे छोटी नॉनजेगेटिव संख्या के बराबर होती है जो प्रवेश की स्थिति के बाईं, या तिरछे उत्तर-पश्चिम में कहीं भी ऊपर दिखाई नहीं देती है।

शीर्ष-बाएं 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)सम या विषम है।

आपके प्रोग्राम में स्रोत कोड के 64 केबी (65,536 बाइट्स) से अधिक नहीं हो सकता है, या 2 एमबी (2,097,152 बाइट्स) से अधिक मेमोरी का उपयोग कर सकता है।

विशेष रूप से स्मृति उपयोग के लिए, इसका मतलब है कि आपके प्रोग्राम का अधिकतम निवासी सेट आकार उस भाषा में एक खाली प्रोग्राम के अधिकतम निवासी सेट आकार से 2 एमबी से अधिक नहीं हो सकता है। एक व्याख्या की गई भाषा के मामले में, यह दुभाषिया / आभासी मशीन का स्मृति उपयोग ही होगा, और एक संकलित भाषा के मामले में, यह एक ऐसे कार्यक्रम का मेमोरी उपयोग होगा जो मुख्य विधि को निष्पादित करता है और कुछ भी नहीं करता है।

आपके कार्यक्रम को 10000 x 10000मैट्रिक्स में पंक्ति मानों 20000 <= x <= 29999और स्तंभ मानों के लिए परखा जाएगा 20000 <= y <= 29999

आपके प्रोग्राम का स्कोर सटीकता दर (सही अनुमानों की संख्या) है, जो आपके प्रोग्राम को प्राप्त करता है, एक छोटे से कोडब्रेकर के रूप में कार्य करता है।


3
01.Rएक 05AB1E है जो यादृच्छिक रूप से सही या गलत आउटपुट करता है। 0 को सत्य होने दें और 1 को गलत होने दें, मेरा कार्यक्रम सैद्धांतिक रूप से ~ 50% समय सही रहेगा। क्या यह एक वैध प्रविष्टि है?
मैजिक ऑक्टोपस Urn

@carusocomputing वास्तव में, मैं यह उल्लेख करना भूल गया कि यादृच्छिक समाधान की अनुमति नहीं है - आपके प्रोग्राम को हर बार एक ही इनपुट के लिए एक ही आउटपुट का उत्पादन करना चाहिए, हालांकि मुझे संदेह है कि शब्द फ़ंक्शन का अर्थ है कि।
जो जेड।

यदि मैं प्रत्येक कॉल पर अपने prng के बीज को ठीक करता हूं, तो यह समान इनपुट के लिए समान आउटपुट का उत्पादन करेगा, और मुझे पता है कि आपका क्या मतलब है, लेकिन आपको शायद इसे किसी विशेष रूप से अधिक शब्द देना होगा।
मील


@ लिनुस "वीथॉफ़्स गेम मैट्रिक्स" बेहतर होगा? मैंने वो पेज भी देखा।
जो जेड।

जवाबों:


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) के लिए सबसे अच्छा अनुमान पढ़ता है । आप Google डिस्क से पूर्ण स्रोत कोड डाउनलोड कर सकते हैं ।

मैंने स्ट्रिंग को जेनरेट करने और सटीकता की गणना करने के लिए @ पीटरटायलर की समानता का उपयोग किया है।


मैंने कई अलग, अधिक दिलचस्प तरीकों की कोशिश की, लेकिन अंत में, एक साधारण हार्डकोड ने उन सभी को बाहर निकाल दिया ...
डेनिस

हार्डकोडिंग भी एक मान्य दृष्टिकोण है - यह कह सकता है कि हार्डकोडिंग योजना सबसे अच्छा परिणाम देती है।
जो जेड।

अन्यथा नहीं कह रहा हूं, लेकिन चूंकि पैरंट्स का वितरण बहुत स्पष्ट रूप से गैर-यादृच्छिक है, इसलिए मैं इस दृष्टिकोण को आउटसोर्स करने की उम्मीद कर रहा था। अब तक, मेरे सभी प्रयास हालांकि विफल रहे हैं।
डेनिस

नहीं, यह ठीक है। इसका मतलब सिर्फ इतना है कि यह समस्या ठीक से करने के लिए बहुत कठिन है। मैं इस शैली की एक समस्या को एक आयामी छोड़कर एक गुच्छा बना रहा हूं। यदि आप उन्हें जांचना चाहते हैं तो वे सभी सैंडबॉक्स में हैं।
जो

4

सीजाम (सटीकता 50016828/100000000, 6 बाइट्स)

{+1&!}

(गैर- CJammers के लिए ALGOL- शैली छद्मकोड में:) return ((x + y) & 1) == 0

यह मेरे द्वारा आजमाए गए अन्य दो दर्जन सरल उत्तराधिकारियों में से किसी से भी बेहतर प्रदर्शन करता है। यह अगले दो सबसे अच्छे लोगों के साथ किसी भी संयोजन से बेहतर है।


स्कोर मानता है कि मैट्रिक्स की मेरी गणना की गई धारा सही है। स्वतंत्र सत्यापन का स्वागत किया। मैं http://cheddarmonk.org/codegolf/PPCG95604-parity.bz2 (8MB डाउनलोड, 50 एमबी पाठ फ़ाइल में अर्क: परिकलित समतुल्य बिट्स की मेजबानी कर रहा हूँ : चूंकि मैट्रिक्स मुख्य विकर्ण के बारे में सममित है, मैंने केवल प्रत्येक को शामिल किया है। मुख्य विकर्ण से शुरू होने वाली रेखा, ताकि आपको ऑफसेट, पारगमन और बिटवाइज़ या पूर्ण वर्ग प्राप्त करने के लिए)।

जिस कोड का मैंने गणना करने के लिए उपयोग किया है वह जावा है। यह परिभाषा का उपयोग काफी सरलता से करता है, लेकिन एक सेट डेटा संरचना के साथ जो रन-लेंथ रेंज को एन्कोड करता है ताकि अगले अनुमत मूल्य पर छोड़ना जल्दी हो। आगे अनुकूलन संभव होगा, लेकिन यह लगभग दो घंटे और 1.5GB के ढेर स्थान में मेरे पुराने पुराने डेस्कटॉप पर चलता है।

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 की गणना करता है और इसे modulo 2 लेता है। A का 0अर्थ है कि यह सम है और 1इसका अर्थ विषम है।

प्रदर्शन @ पीटर टेलर द्वारा प्रदत्त समता बिट्स पर आधारित है ।

7 बाइट्स से पहले PRNG संस्करण की 2|?.@#.सटीकता 50010491/10 8 थी

व्याख्या

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

1
एलसीएम की समता बिटवाइज़ की समानता है और। क्या इससे आपको बाइट बचती है? आकर्षक बात यह है कि यह इतना स्पष्ट रूप से एक खराब अनुमानी है (यह 1समय का मात्र 25% देता है, जब सही अनुपात लगभग 50% होता है), और फिर भी यह कई से बेहतर करता है जो कि स्पष्ट रूप से बुरा नहीं है।
पीटर टेलर

धन्यवाद, लेकिन दुर्भाग्य से बिटवाइंड और जे में शाब्दिक है AND
मील

@PeterTaylor इस तरह की हैरतअंगेज खोज करने के बाद इस तरह की चुनौतियों का सामना करना पड़ता है।
जो जेड।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.