यूनिवर्सल (नियम-झुकने) कोड गोल्फ सॉल्वर


14

कोड गोल्फ में हमेशा कुछ ऐसे उत्तर शामिल होते हैं जो नियमों को कम या ज्यादा करके उन बाधाओं को तोड़ते हैं, जिन्हें चुनौती देने वाले ने लिया था या नियमों के बारे में सोचा नहीं था। इन दिलचस्प खामियों में से एक बेहतर परिणाम प्राप्त करने के लिए चुनौती से अधिक उत्पादन करने की संभावना है ।

इसे चरम सीमा पर ले जाते हुए, हम एक सार्वभौमिक कोड गोल्फ सॉल्वर लिख सकते हैं जो वांछित आउटपुट को प्रिंट करता है - अगर आपको परवाह नहीं है कि यह उम्र ले सकता है और इसके पहले और बाद में बहुत सारे अन्य सामानों को आउटपुट करता है।

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

अनुक्रम तीन बिट्स 010 से शुरू होता है; प्रत्येक क्रमिक अंक उस अनुक्रम के सबसे लंबे प्रत्यय को खोजने से बनता है, जो पहले अनुक्रम में भी दिखाई देता है, और उस प्रत्यय के सबसे हाल के स्वरूप के बाद बिट को पूरक करता है।

बिट्स की प्रत्येक परिमितता क्रमिक रूप से, क्रम के भीतर असीम रूप से होती है

अनुक्रम के पहले कुछ अंक हैं:

010011010111000100001111 ... ( OEIS में अनुक्रम A038219 )।

अनुक्रम के 8 बिट्स को बाइट के साथ जोड़कर, हम ASCII आउटपुट प्राप्त करेंगे जिसे हम स्क्रीन पर या किसी फ़ाइल में आउटपुट कर सकते हैं और जिसमें हर संभव परिमित आउटपुट शामिल है । कार्यक्रम पीआई के कुछ हिस्सों का उत्पादन करेगा, "कभी भी तुम्हें देने वाला नहीं है" के बोल , कुछ अच्छा ASCII कला, इसका अपना स्रोत कोड, और बाकी सब कुछ आप इसे आउटपुट के लिए चाहते हैं।

शुद्धता के परीक्षण के लिए, यहाँ अनुक्रम के पहले 256 बाइट्स के लिए हैश हैं:

MD5: 5dc589a06e5ca0cd9280a364a456d7a4
SHA-1: 657722ceef206ad22881ceba370d32c0960e267f

हेक्साडेसिमल संकेतन में अनुक्रम के पहले 8 बाइट्स हैं:

4D 71 0F 65 27 46 0B 7C

नियम:

  • आपके प्रोग्राम को बाइट / ASCII कैरेक्टर के 8 बिट्स को मिलाकर Ehrenfeucht-Mycielski अनुक्रम (और कुछ नहीं) का उत्पादन करना चाहिए।

  • सबसे छोटा कार्यक्रम (वर्ण गणना) जीतता है। अपने वर्ण गणना से 512 को घटाएं यदि आप उत्पन्न बाइट में रैखिक समय में अनुक्रम उत्पन्न करने का प्रबंधन करते हैं


010 में सबसे लंबा प्रत्यय जो उस क्रम में पहले दिखाई दिया था 0, है ना? और सबसे हाल ही में पहले की उपस्थिति सिर्फ दूसरी है 0. और अब तक, कुछ भी दूसरे 0 का अनुसरण नहीं करता है, इसलिए ऐसा कुछ भी नहीं है जिस पर हम एक पूरक का निर्माण कर सकते हैं। मैं एक देशी अंग्रेजी बोलने वाला नहीं हूँ - शायद मैं इसे गलत समझ गया। विकिपीडिया लेख समान शब्दों का उपयोग करता है, लेकिन एक लंबा अनुक्रम है इसलिए मैं इसे "सबसे हाल का ... जिसका एक अनुयायी है" नाम देगा।
उपयोगकर्ता अज्ञात

8
पैदाइशी वक्रोक्ति: पाई कभी प्रकट नहीं होगी - केवल हर परिमित स्ट्रिंग आउटपुट में समाहित होगी।
कीथ रान्डेल

मेरे पास एक और सवाल है: एक पुनरावृत्ति ओवरलैप हो सकती है? उदाहरण के लिए 111 में, (1 [1) 1]?
उपयोगकर्ता अज्ञात

@KeithRandall: मैं एक ऐसे अनुक्रम को पसंद करूंगा जिसमें 'कभी भी आपको हार न मानने' और इसी तरह की प्रस्तुतियों को शामिल न करने की गारंटी हो।
उपयोगकर्ता अनजान

2
यह उल्लेख के लायक हो सकता है कि एक अनंत स्ट्रिंग में अनिर्दिष्ट स्थान पर "उत्तर" के मात्र उपस्थिति को "आउटपुटिंग" के रूप में नहीं माना जा सकता है, जो निश्चित रूप से उत्तर देता है। इसके अलावा, यह विशेष अनुक्रम एक विवादास्पद अनुक्रम का सिर्फ एक उदाहरण है - इस तरह असीम रूप से कई अनुक्रम हैं।
रेस

जवाबों:


7

सी, -110 चरस

कार्यक्रम का यह संस्करण अनुक्रम उत्पन्न करने के लिए रैखिक-रनटाइम एल्गोरिथ्म का उपयोग करता है। कार्यक्रम में 402 वर्णों में से 512 घटाकर कुल नकारात्मक 110 मिलता है।

#define C v=calloc(7,8),v->p=p
#define G(F,K)u->F[d[K]]
#define S(F,T)G(f,T)=F,G(t,T)=T,G(n,T)=
struct{int p,f[2],t[2];void*n[2];}r,*u,*v,*w;char*d,c;p,b,h,i,j,k;
main(s){for(;d=++p-s?d:realloc(d,s*=2);){d[i=p]=b;c+=c+b;p%8||putchar(c);
for(u=&r;b=u->p,u->p=p,w=G(n,k=i);S(i,k)v=G(n,k),u=v)for(h=G(f,k),j=G(t,k);j>h;--i,--j)
if(d[i]-d[j]){S(i,k)C;u=v;S(h,j)w;S(0,i)C;b=w->p;goto x;}S(0,i)C;x:b=1-d[b+1];}}

समस्या के अनुसार, कार्यक्रम एक अनंत लूप में चलता है, जिसमें बहुत सारे मेमोरी आवंटन की आवश्यकता होती है, और realloc()अनुक्रम को सन्निहित रखने के लिए उपयोग करने से विखंडन में सुधार हो सकता है। आप calloc(7,8)पहली पंक्ति पर प्रतिस्थापित करके प्रोग्राम की मेमोरी उपयोग में सुधार कर सकते हैं calloc(1,sizeof*v)। यह 32-बिट मशीन पर विशेष रूप से मदद करेगा, जहां 56 दो के कारक से बहुत बड़ा है।

कोड अप्राप्य की तरह है, और दिलचस्प तरीके से नहीं; इसके लिए मैं माफी चाहता हूं। सच कहूं, तो भी ungolfed संस्करण बहुत स्पष्ट नहीं है:

#include <stdio.h>
#include <stdlib.h>

typedef struct branch branch;
typedef struct node node;

struct branch {
    int from, to;
    node *next;
};

struct node {
    int pos;
    branch br[2];
};

static node root = { 0 };

static unsigned char *data = NULL;
static int endpos = 0;
static int size = 1;

static node *mknode(void)
{
    node *n;

    n = calloc(1, sizeof *n);
    n->pos = endpos;
    return n;
}

static branch *getbranch(node *n, int p)
{
    return &n->br[data[p]];
}

static void setbranch(node *n, int from, int to, node *next)
{
    n->br[data[to]].next = next;
    n->br[data[to]].from = from;
    n->br[data[to]].to = to;
}

int main(void)
{
    node *u, *v, *w;
    int follower, from, i, i0, j;
    int out, b;

    out = b = 0;
    for (;;) {
        ++endpos;
        if (endpos == size) {
            size *= 2;
            data = realloc(data, size);
        }
        data[endpos] = b;
        out = (out << 1) | b;
        if (endpos % 8 == 0) {
            putchar(out);
            out = 0;
        }

        i = endpos;
        u = &root;
        for (;;) {
            follower = u->pos + 1;
            u->pos = endpos;
            w = getbranch(u, i)->next;
            if (!w)
                break;
            i0 = i;
            from = getbranch(u, i0)->from;
            for (j = getbranch(u, i0)->to ; j > from ; --j) {
                if (data[i] != data[j]) {
                    /* divide branch */
                    v = mknode();
                    setbranch(u, i, i0, v);
                    u = v;
                    setbranch(u, from, j, w);
                    setbranch(u, 0, i, mknode());
                    follower = w->pos + 1;
                    goto bitfound;
                }
                --i;
            }
            v = getbranch(u, i0)->next;
            setbranch(u, i, i0, v);
            u = v;
        }
        /* extend branch */
        setbranch(u, 0, i, mknode());

      bitfound:
        b = 1 - data[follower];
    }
}

(ऊपर दिया गया अनगॉल्ड कोड समस्या के विवरण में संदर्भित सोलज़ेर्मन हरमन और माइकल सॉल्टी द्वारा लिखे गए कोड पर आधारित है, और सॉल्टीज़ के होम पेज से है ।)

प्रारंभिक संस्करण में बग की रिपोर्ट करने के लिए @schnaader और @res का धन्यवाद।


अच्छा! यही कारण है कि मैंने -512 बोनस की उम्मीद की थी।
श्नाडर

किसी भी विचार क्यों यह प्रणाली द्वारा दुर्घटनाओं का कारण बनता है? सभी गॉल्फ़्ड, अनगोल्डेड और mallocसंशोधित संस्करण लगभग 10000 बाइट्स के बाद आउटपुट बंद कर देते हैं और मेमोरी आवंटित करते रहते हैं, prog > out.datकेवल ~ 700 KB मेमोरी उपयोग के साथ त्वरित दुर्घटना देता है। अगर मैं डालने printf("\n%i\n", size);के बाद realloc, सबसे बड़ी उत्पादन होता है 4। सिस्टम: विंडोज 7 प्रो। 64-बिट, 4 जीबी रैम, जीसीसी 4.6.1
श्नाइडर

(+1) मुझे लगता है कि Ubuntu12.04 / gcc के साथ, आपके दोनों प्रोग्राम्स कंपाइल करते हैं और सही आउटपुट देते हैं ... Win7 / mingw / gcc के साथ, दोनों प्रोग्राम कंपाइल करते हैं, लेकिन सेगमेंट दोष उत्पन्न करते हैं ... Win7 / lcc के साथ ungolfed संस्करण काम करता है, लेकिन गोल्फ संस्करण विभाजन दोष पैदा करता है।
रेस

1
यह मेरे लिए एकतरफा डेटा के उपयोग की तरह लगता है। निश्चित रूप से पर्याप्त - मेरे पास विंडोज मशीन तक पहुंच नहीं है, लेकिन वैलेग्रिंड समस्या को दर्शाता है। ऐसा लगता है कि मैंने मूल संदर्भ कार्यान्वयन से भी इस बग को पुन: पेश किया। सौभाग्य से यह एक आसान तय है; इसे रिपोर्ट करने के लिए धन्यवाद!
ब्रेडबॉक्स

महान, अब एक आकर्षण की तरह काम करता है।
श्नाडर

6

रूबी, 109 104 101 94 वर्ण

s=?0
loop{s=(s[/(.*).*\1/][/.#{$1}/]<?1??1:?0)+s
s.size&7<1&&$><<[s.reverse.to_i(2)].pack(?C)}

प्रत्यय खोज के लिए नियमित अभिव्यक्ति का उपयोग करते हुए रूबी में कार्यान्वयन। चूंकि आउट-ऑफ-मेमरी में काफी लंबा समय लगता है इसलिए प्रोग्राम को यूजर द्वारा समाप्त किया जाना चाहिए।

संपादित करें: मैंने अभी देखा कि यह अनुक्रम से शुरू करने के लिए पर्याप्त है 0

संपादित करें 2: रेस का प्रस्ताव 2 पात्रों को बचाता है, कुछ अन्य क्योंकि हमें पहले एक भी बाइट नहीं काटनी है pack


उपयोग करने s=(s[/(.*).*\1/][/.#{$1}/]<?1??1:?0)+sसे एक और दो अक्षर बचेंगे।
रेस

@res यह वास्तव में काम करता है। धन्यवाद।
हॉवर्ड

क्या आप चारों ओर कोष्ठक से छुटकारा पा सकते हैं ?C?
निधि मोनिका का मुकदमा

4

पर्ल, 95 चार्ट

मैं वास्तव में पहली बार में इसका एक आधा सभ्य संस्करण था। फिर जैसे ही मैंने गोल्फ किया, प्रत्येक संस्करण धीमा हो गया। लगातार धीमी गति से बढ़ रहा है।

$|=$_="010";
y///c%8||print pack"B*",/(.{8})$/while/(.+)$(?(?{m|.*$^N(.)|})(?{$_.=1-$^N})|(?!))/

पहले तीन अक्षर ( $|=) आवश्यक नहीं हैं, कड़ाई से बोल रहे हैं ... लेकिन इसके बिना, आपको आमतौर पर स्क्रिप्ट का इंतजार करना होगा ताकि आप किसी भी आउटपुट को देखने से पहले पूरी 4096 बाइट्स उत्पन्न कर सकें। और इसमें घंटों लगेंगे। शायद सदियाँ; मुझे यकीन नहीं है। क्या मैंने उल्लेख किया है कि इस कार्यक्रम का प्रदर्शन समय के साथ बिगड़ता जा रहा है? तो इस वजह से मैंने उन्हें गिनती में शामिल करने के लिए मजबूर महसूस किया।

दूसरी ओर, इस स्क्रिप्ट में मेरे द्वारा बनाई गई सबसे बदसूरत रेगीक्स में से एक है, इसलिए मुझे लगता है कि मुझे इस पर गर्व है।


1
प्रदर्शन के बारे में चिंता न करें, एल्गोरिथ्म ओ (एन ^ 3) है बिना अनुकूलन के। मेरा सरल डेल्फी कार्यक्रम मैंने लिखा था कि 256 बाइट्स के लिए लगभग 30 सेकंड लगते हैं, लेकिन 1024 बाइट्स के लिए एक घंटे के बारे में, इसलिए मैं एक या कई दिनों के लिए 4096 बाइट्स मानूंगा। बेशक, RegEx और अंतरिक्ष अनुकूलन में इसे और खराब करने की क्षमता है :)
श्नाइडर

मेरी प्रारंभिक पर्ल स्क्रिप्ट को 256 बाइट्स के लिए 10 सेकंड का समय लगा। इस संस्करण में 90 सेकंड लगते हैं। (और न ही यह एक रैखिक मंदी प्रतीत होता है।)
ब्रेडबॉक्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.