संदर्भ मुक्त व्याकरण के साथ डेटा संपीड़ित करें


9

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

इनपुट

इनपुट 65535 बाइट्स लंबाई की एक स्ट्रिंग नहीं है। यह गारंटी है, कि इनपुट नियमित अभिव्यक्ति से मेल खाता है [!-~]+(यानी व्हाट्सएप को छोड़कर कम से कम एक मुद्रण योग्य ASCII चरित्र)।

एक उदाहरण इनपुट है

abcabcbcbcabcacacabcabab

उत्पादन

आउटपुट नियमों का एक समूह है जो एक व्याकरण बनाता है जो बिल्कुल एक शब्द (इनपुट) का वर्णन करता है। प्रत्येक nonterminal को दशमलव संख्या 9. से अधिक द्वारा निरूपित किया जाता है। प्रारंभ चिन्ह प्रतीक संख्या दस है। उदाहरण इनपुट के अनुरूप एक उदाहरण आउटपुट नीचे दिया गया है; इसके सिंटैक्स का वर्णन नीचे किया गया है:

10=11 11 12 12 11 13 13 11 14 14
11=a 12
12=b c
13=a c
14=a b

प्रत्येक नियम में <nonterminal>=<symbol> <symbol> ...दाईं ओर एक अनियंत्रित व्हॉट्सएप-अलग-अलग प्रतीकों की संख्या होती है। प्रत्येक आउटपुट जो निम्न प्रतिबंधों का पालन करता है और वास्तव में इनपुट स्ट्रिंग मान्य है।

प्रतिबंध

लोगों को अजीब चीजें करने से रोकने के लिए, कई तरह की पाबंदियां लग रही हैं:

  • प्रत्येक नॉनटर्मिनल को एक नियम के दाईं ओर कम से कम दो बार दिखाई देना चाहिए। उदाहरण के लिए, इनपुट के लिए निम्नलिखित व्याकरण abcabcअवैध है क्योंकि नियम 12 केवल एक बार दिखाई देता है:

    10=12
    11=a b c
    12=11 11
    
  • दो आसन्न प्रतीकों का कोई अनुक्रम सभी नियमों के सभी दाएं हाथ के किनारों में एक से अधिक बार दिखाई नहीं दे सकता है, भले ही वे ओवरलैप करें। उदाहरण के लिए, इनपुट के लिए निम्नलिखित व्याकरण abcabcbcअवैध है क्योंकि अनुक्रम bcदो बार दिखाई देता है:

    10=11 11 b c
    11=a b c
    

    एक मान्य व्याकरण होगा:

    10=11 11 12
    11=a 12
    12=b c
    
  • आपका प्रोग्राम प्रत्येक वैध इनपुट के लिए एक मिनट से भी कम समय में समाप्त होना चाहिए जो 65535 बाइट्स से अधिक नहीं है।

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

नमूना इनपुट

निम्नलिखित सी कार्यक्रम के साथ नमूना इनपुट उत्पन्न करें।

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

int main(int argc, char **argv) {
  unsigned int i,j = 0,k;

  if (argc != 3
     || 2 != sscanf(argv[1],"%u",&i)
      + sscanf(argv[2],"%u",&k)) {
    fprintf(stderr,"Usage: %s seed length\n",argv[0]);
    return EXIT_FAILURE;
  }

  srand(i);

  while(j < k) {
    i = rand() & 0x7f;
    if (i > 34 && i != 127) j++, putchar(i);
  }

  return EXIT_SUCCESS;
}

ऊपर कार्यक्रम द्वारा उत्पन्न नमूना इनपुट आमतौर पर अच्छे संपीड़न परिणाम नहीं देगा। उदाहरण इनपुट के रूप में मानव पाठ या स्रोत कोड का उपयोग करने पर विचार करें।

मानदंड जीतना

यह कोड गोल्फ है; कम से कम स्रोत कोड जीत के साथ कार्यक्रम। अतिरिक्त क्रेडिट के लिए, एक प्रोग्राम लिखें जो आउटपुट से इनपुट को फिर से संगठित करता है।


हा हा! मेरे पास पहले से ही कार्यान्वित (लेकिन गोल्फ नहीं) के कुछ संस्करण जावा में कोल्मोगोरोव-जटिलता के सवालों के लिए हैं ...
पीटर टेलर

@PeterTaylor वास्तव में कौन से प्रश्न?
फ़ूजएक्सएक्सएल

यह जरूरी नहीं कि पोस्ट करने लायक होने के लिए एक छोटा सा पर्याप्त उत्तर हो (मैं व्याकरण उत्पन्न करने वाली रणनीतियाँ और व्याकरण इंजनों को धीरे-धीरे जोड़ रहा हूँ), लेकिन उस परियोजना की मूल स्क्रिप्ट कोडगुल्फ़.स्टैकएक्सचेंज . com/ questions / 1682 , कोडगुल्फ़ पर उन्हें आज़माती है .stackexchange.com / questions / 6043 , codegolf.stackexchange.com/questions/4191 , codegolf.stackexchange.com/questions/4356 और अन्य प्रश्नों के कुछ घटक।
पीटर टेलर

जवाबों:


3

गोल्फस्क्रिप्ट, 111 108 वर्ण

1/{.}{:^1<{^1$/,2>.{;,)^<.0?)!}*}do-1<.,1>{^1$/[10):10]*0+\+}{;^}if(\}while][0]%.,,]zip{))9+`"="+\~" "*+}%n*

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

उदाहरण:

> abcba
10=a b c b a

> abcabcbc
10=11 11 12
11=a 12
12=b c

> abcabcbcbcabcacacabcabab
10=11 12 12 13 14 14 c 11 15
11=15 13
12=c b
13=14 b
14=c a
15=a b

1

वापस ले लिया - एल्गोरिथ्म सभी मामलों को संभाल नहीं सकता। सी, 422 (आउटपुट में डंप को हटाने के लिए तय किया गया, और गिरा हुआ चरित्र)

प्रारंभिक कार्यान्वयन, इसे शुरू करना होगा।

चूंकि नियम यह वास्तव में करने के लिए की आवश्यकता नहीं है सेक इस जानवर बल भोली दृष्टिकोण क्या करेंगे ...

10 सेकंड के भीतर 65535 लंबाई प्रक्रिया कर सकते हैं

n,m[99999];
c,r[99999][2];

g,i,s,t;

main(){
    for(;(m[n]=getchar())>32;n++);

    while(!g){ // loop until no further changes
        g=1;
        for(s=0;s<n-1;s++) {
            for(t=s+2;t<n-1;t++)if(m[s]==m[t]&&m[s+1]==m[t+1]){
                // create rule
                r[c][0]=m[s];
                r[c++][1]=m[s+1];
                g=0;
                // substitute
                for(i=t=s;i<n;i++){
                    if(m[i]==r[c-1][0]&&m[i+1]==r[c-1][1]){
                        m[t++]=-c;
                        i++;
                    }else
                        m[t++]=m[i];
                }
                n=t;
            }
        }
    }

    for(s=-1;s<c;s++){
        printf("%d=",s+11);
        for(t=0;t<(s<0?n:2);t++){
            i=(s<0?m:r[s])[t];
            i<0?printf("%d ",10-i):printf("%c ",i);
        }
        printf("\n");
    }

}

नमूना रन:

echo abcabcbcbcabcacacabcabab | a.out
10=11 12 13 13 12 14 14 12 12 11 
11=a b 
12=c 11 
13=c b 
14=c a


आपका कोड doe विनिर्देश के अनुसार काम नहीं करता है। यह आउटपुट उत्पन्न करता है जो नियम का उल्लंघन करता है दो वर्णों का कोई अनुक्रम दो बार प्रकट हो सकता है ; इनपुट abcdabcd पर विचार करें। इसके अलावा, आपका कोड जाहिरा तौर पर इनपुट स्ट्रीम से अंतिम बाइट निकालता है। दोनों प्रभावों का पालन करने के लिए एक उदाहरण के लिए यहां देखें: ideone.com/3Xvtyv
FUZxxl

इसके अलावा, आपका नमूना आउटपुट स्पष्ट रूप से गलत है।
फूजएक्सएक्सएल

आप सही हैं - मैं विफल रहा - जब मैं काम से वापस आऊंगा तो मैं इसे
बेबी-खरगोश

यह मेरे लिए इनपुट से अंतिम बाइट नहीं निकाल रहा है - और मेरा नमूना आउटपुट सही है (मेरे लिए) .. चलो "स्पॉट द बग" खेलें!
बेबी-खरगोश

आपके द्वारा निश्चित रूप से पोस्ट किया गया नमूना आउटपुट है। नियम 10 का विस्तारित रूप नियम 14 के साथ समाप्त होता है जो बदले में "सीए" के साथ समाप्त होता है। अंतिम सी वास्तव में अंत से पहले 5 स्थिति है।
FUZxxl
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.