गोल्फ मेरे "पूर्व गोल्फ" सी


12

पृष्ठभूमि

सी में मेरे सबमिशन के लिए, मुझे एक प्रोसेसिंग टूल की आवश्यकता है। कई अन्य भाषाओं की तरह, व्हॉट्सएप C स्रोत में ज्यादातर अप्रासंगिक है (लेकिन हमेशा नहीं!) - फिर भी यह कोड मनुष्यों के लिए अधिक व्यापक बनाता है। एक पूरी तरह से तैयार सी कार्यक्रम जिसमें एक भी निरर्थक व्हाट्सएप शामिल नहीं है, अक्सर मुश्किल से पढ़ा जा सकता है।

इसलिए, मुझे सीटी जमा करने के लिए सी में अपना कोड लिखना पसंद है जिसमें व्हॉट्सएप और कभी-कभी टिप्पणियां भी शामिल हैं, इसलिए कार्यक्रम लिखते समय एक समझदार संरचना रखता है। अंतिम चरण सभी टिप्पणियों और अनावश्यक व्हाट्सएप को हटाना है। यह एक थकाऊ और नासमझ कार्य है जो वास्तव में एक इंटर्न कंप्यूटर प्रोग्राम द्वारा किया जाना चाहिए ।

कार्य

एक प्रोग्राम या फ़ंक्शन लिखें जो टिप्पणियों और निरर्थक व्हाट्सएप को कुछ "पूर्व-गढ़वाले" सी स्रोत से निम्नलिखित के अनुसार समाप्त करता है:

  • A \(बैकस्लैश) एक पंक्ति में अंतिम वर्ण के रूप में एक पंक्ति निरंतरता है । यदि आपको यह पता चलता है, तो आपको निम्न पंक्ति को उसी तार्किक रेखा के भाग के रूप में समझना चाहिए (उदाहरण के लिए आप \और \nकुछ भी करने से पहले और ( निम्नलिखित ) पूरी तरह से हटा सकते हैं)
  • टिप्पणियां केवल एक-पंक्ति प्रारूप का उपयोग करेंगी, जिसके साथ शुरुआत होगी //। इसलिए उन्हें हटाने के लिए, आप जहाँ भी आप //एक स्ट्रिंग शाब्दिक (नीचे देखें) के बाहर मुठभेड़ करते हैं, बाकी तार्किक रेखा को अनदेखा करते हैं।
  • व्हॉट्सएप के पात्र (स्थान), \t(टैब) और \n(नई रेखा, इसलिए यहां तार्किक रेखा का अंत है)।
  • जब आप व्हॉट्सएप का एक क्रम पाते हैं, तो उसके आसपास के गैर-व्हाट्सएप पात्रों की जांच करें। अगर

    • वे दोनों अल्फ़ान्यूमेरिक या अंडरस्कोर (रेंज [a-zA-Z0-9_]) या हैं
    • दोनों हैं +या
    • दोनों हैं -या
    • पूर्ववर्ती एक है /और निम्नलिखित एक है*

    फिर अनुक्रम को एकल स्थान ( ) वर्ण से बदलें ।

    अन्यथा, अनुक्रम को पूरी तरह से समाप्त करें।

    इस नियम के कुछ अपवाद हैं :

    • प्रीप्रोसेसर निर्देश आपके आउटपुट में अपनी खुद की लाइनों पर दिखाई देने चाहिए। एक प्रीप्रोसेसर निर्देश के साथ शुरू होने वाली एक रेखा है #
    • एक स्ट्रिंग शाब्दिक या वर्ण शाब्दिक के अंदर , आपको कोई व्हाट्सएप नहीं निकालना चाहिए। कोई भी "(डबल-उद्धरण) / '(एकल-उद्धरण) जो किसी विषम संख्या के बैकस्लैश से पहले से आगे नहीं बढ़ा है ( \) एक स्ट्रिंग शाब्दिक / वर्ण शाब्दिक शुरू या समाप्त होता है । आपको गारंटी है कि स्ट्रिंग और चरित्र शाब्दिक उसी पंक्ति पर समाप्त होते हैं जो उन्होंने शुरू किया था। स्ट्रिंग शाब्दिक और चरित्र शाब्दिक रूप से नेस्टेड नहीं हो सकते हैं, इसलिए एक स्ट्रिंग शाब्दिक के' अंदर , साथ ही एक चरित्र शाब्दिक के अंदर कोई विशेष अर्थ नहीं है।"

मैं / हे विनिर्देशन

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

आप मान सकते हैं कि इनपुट एक वैध सी प्रोग्राम सोर्स कोड है। इसका अर्थ यह भी है कि इसमें केवल मुद्रण योग्य ASCII वर्ण, टैब और नए अंक शामिल हैं। विकृत इनपुट पर अपरिभाषित व्यवहार की अनुमति है।

व्हाट्सएप / खाली लाइनों के लिए अग्रणी और अनुगामी अनुमति नहीं है

परीक्षण के मामलों

  1. इनपुट

    main() {
        printf("Hello, World!"); // hi
    }
    

    उत्पादन

    main(){printf("Hello, World!");}
    
  2. इनपुट

    #define max(x, y) \
        x > y ? x : y
    #define I(x) scanf("%d", &x)
    a;
    b; // just a needless comment, \
            because we can!
    main()
    {
        I(a);
        I(b);
        printf("\" max \": %d\n", max(a, b));
    }
    

    उत्पादन

    #define max(x,y)x>y?x:y
    #define I(x)scanf("%d",&x)
    a;b;main(){I(a);I(b);printf("\" max \": %d\n",max(a,b));}
    
  3. इनपुट

    x[10];*c;i;
    main()
    {
        int _e;
        for(; scanf("%d", &x) > 0 && ++_e;);
        for(c = x + _e; c --> x; i = 100 / *x, printf("%d ", i - --_e));
    }
    

    उत्पादन

    x[10];*c;i;main(){int _e;for(;scanf("%d",&x)>0&&++_e;);for(c=x+_e;c-->x;i=100/ *x,printf("%d ",i- --_e));}
    
  4. इनपुट

    x;
    #include <stdio.h>
    int main()
    {
        puts("hello // there");
    }
    

    उत्पादन

    x;
    #include<stdio.h>
    int main(){puts("hello // there");}
    
  5. इनपुट (एक वास्तविक दुनिया उदाहरण)

    // often used functions/keywords:
    #define P printf(
    #define A case
    #define B break
    
    // loops for copying rows upwards/downwards are similar -> macro
    #define L(i, e, t, f, s) \
            for (o=i; o e;){ strcpy(l[o t], l[o f]); c[o t]=c[s o]; }
    
    // range check for rows/columns is similar -> macro
    #define R(m,o) { return b<1|b>m ? m o : b; }
    
    // checking for numerical input is needed twice (move and print command):
    #define N(f) sscanf(f, "%d,%d", &i, &j) || sscanf(f, ",%d", &j)
    
    // room for 999 rows with each 999 cols (not specified, should be enough)
    // also declare "current line pointers" (*L for data, *C for line length),
    // an input buffer (a) and scratch variables
    r, i, j, o, z, c[999], *C, x=1, y=1;
    char a[999], l[999][999], (*L)[999];
    
    // move rows down from current cursor position
    D()
    {
        L(r, >y, , -1, --)
        r++ ? strcpy(l[o], l[o-1]+--x), c[o-1]=x, l[o-1][x]=0 : 0;
        c[y++] = strlen(l[o]);
        x=1;
    }
    
    // move rows up, appending uppermost to current line
    U()
    {
        strcat(*L, l[y]);
        *C = strlen(*L);
        L(y+1, <r, -1, , ++)
        --r;
        *l[r] = c[r] = 0;
    }
    
    // normalize positions, treat 0 as max
    X(b) R(c[y-1], +1)
    Y(b) R(r, )
    
    main()
    {
        for(;;) // forever
        {
            // initialize z as current line index, the current line pointers,
            // i and j for default values of positioning
            z = i = y;
            L = l + --z;
            C = c + z;
            j = x;
    
            // prompt:
            !r || y/r && x > *C
                ? P "end> ")
                : P "%d,%d> ", y, x);
    
            // read a line of input (using scanf so we don't need an include)
            scanf("%[^\n]%*c", a)
    
                // no command arguments -> make check easier:
                ? a[2] *= !!a[1],
    
                // numerical input -> have move command:
                // calculate new coordinates, checking for "relative"
                N(a)
                    ? y = Y(i + (i<0 | *a=='+') * y)
                        , x = X(j + (j<0 || strchr(a+1, '+')) * x)
                    :0
    
                // check for empty input, read single newline
                // and perform <return> command:
                : ( *a = D(), scanf("%*c") );
    
            switch(*a)
            {
                A 'e':
                    y = r;
                    x = c[r-1] + 1;
                    B;
    
                A 'b':
                    y = 1;
                    x = 1;
                    B;
    
                A 'L':
                    for(o = y-4; ++o < y+2;)
                        o<0 ^ o<r && P "%c%s\n", o^z ? ' ' : '>', l[o]);
                    for(o = x+1; --o;)
                        P " ");
                    P "^\n");
                    B;
    
                A 'l':
                    puts(*L);
                    B;
    
                A 'p':
                    i = 1;
                    j = 0;
                    N(a+2);
                    for(o = Y(i)-1; o<Y(j); ++o)
                        puts(l[o]);
                    B;
    
                A 'A':
                    y = r++;
                    strcpy(l[y], a+2);
                    x = c[y] = strlen(a+2);
                    ++x;
                    ++y;
                    B;
    
                A 'i':
                    D();
                    --y;
                    x=X(0);
                    // Commands i and r are very similar -> fall through
                    // from i to r after moving rows down and setting
                    // position at end of line:
    
                A 'r':
                    strcpy(*L+x-1, a+2);
                    *C = strlen(*L);
                    x = 1;
                    ++y > r && ++r;
                    B;
    
                A 'I':
                    o = strlen(a+2);
                    memmove(*L+x+o-1, *L+x-1, *C-x+1);
                    *C += o;
                    memcpy(*L+x-1, a+2, o);
                    x += o;
                    B;
    
                A 'd':
                    **L ? **L = *C = 0, x = 1 : U();
                    y = y>r ? r : y;
                    B;
    
                A 'j':
                    y<r && U();
            }
        }
    }
    

    उत्पादन

    #define P printf(
    #define A case
    #define B break
    #define L(i,e,t,f,s)for(o=i;o e;){strcpy(l[o t],l[o f]);c[o t]=c[s o];}
    #define R(m,o){return b<1|b>m?m o:b;}
    #define N(f)sscanf(f,"%d,%d",&i,&j)||sscanf(f,",%d",&j)
    r,i,j,o,z,c[999],*C,x=1,y=1;char a[999],l[999][999],(*L)[999];D(){L(r,>y,,-1,--)r++?strcpy(l[o],l[o-1]+--x),c[o-1]=x,l[o-1][x]=0:0;c[y++]=strlen(l[o]);x=1;}U(){strcat(*L,l[y]);*C=strlen(*L);L(y+1,<r,-1,,++)--r;*l[r]=c[r]=0;}X(b)R(c[y-1],+1)Y(b)R(r,)main(){for(;;){z=i=y;L=l+--z;C=c+z;j=x;!r||y/r&&x>*C?P"end> "):P"%d,%d> ",y,x);scanf("%[^\n]%*c",a)?a[2]*=!!a[1],N(a)?y=Y(i+(i<0|*a=='+')*y),x=X(j+(j<0||strchr(a+1,'+'))*x):0:(*a=D(),scanf("%*c"));switch(*a){A'e':y=r;x=c[r-1]+1;B;A'b':y=1;x=1;B;A'L':for(o=y-4;++o<y+2;)o<0^o<r&&P"%c%s\n",o^z?' ':'>',l[o]);for(o=x+1;--o;)P" ");P"^\n");B;A'l':puts(*L);B;A'p':i=1;j=0;N(a+2);for(o=Y(i)-1;o<Y(j);++o)puts(l[o]);B;A'A':y=r++;strcpy(l[y],a+2);x=c[y]=strlen(a+2);++x;++y;B;A'i':D();--y;x=X(0);A'r':strcpy(*L+x-1,a+2);*C=strlen(*L);x=1;++y>r&&++r;B;A'I':o=strlen(a+2);memmove(*L+x+o-1,*L+x-1,*C-x+1);*C+=o;memcpy(*L+x-1,a+2,o);x+=o;B;A'd':**L?**L=*C=0,x=1:U();y=y>r?r:y;B;A'j':y<r&&U();}}}
    

यह , इसलिए सबसे छोटा (बाइट्स में) वैध उत्तर जीतता है।



जवाबों:


4

पिप , 148 135 133 138 बाइट्स

aRM"\
"R`("|').*?(?<!\\)(\\\\)*\1`{lPBaC:++i+191}R[`//.*``#.*`{X*aJw.`(?=`}.')M[A`\w`RL2"++""--""/*"]w`¶+`'·C(192+,#l)][x_WR'¶{aRw'·}xnsl]

बाइट्स में गिने जाते हैं सी.पी.-1252 है, तो और ·प्रत्येक बाइट से एक हैं। ध्यान दें कि यह सी कोड को एक एकल कमांड-लाइन तर्क के रूप में उम्मीद करता है, जो (वास्तविक कमांड लाइन पर) प्रचुर भागने के अनुक्रम के उपयोग की आवश्यकता होगी। इसे ऑनलाइन आज़माना बहुत आसान है !

थोड़े से अनगढ़ संस्करण की व्याख्या

कोड कुछ चालों के साथ प्रतिस्थापन कार्यों का एक गुच्छा करता है।

बैकस्लैश निरंतरता

हम RMसभी शाब्दिक स्ट्रिंग की घटनाएँ हैं

"\
"

वह है, बैकस्लैश और उसके बाद न्यूलाइन।

स्ट्रिंग और चरित्र शाब्दिक

हम कॉलबैक फ़ंक्शन के साथ रेगेक्स प्रतिस्थापन का उपयोग करते हैं:

`("|').*?(?<!\\)(\\\\)*\1`

{
 lPBa
 C(++i + 191)
}

रेगेक्स एक एकल या दोहरे उद्धरण से मेल खाता है, इसके बाद एक गैर-लालची है .*?जो 0 या अधिक वर्णों से मेल खाता है, जितना संभव हो उतना कम। हमारे पास यह सुनिश्चित करने के लिए एक नकारात्मक है कि पिछला चरित्र बैकस्लैश नहीं था; फिर हम बैकलैश की एक समान संख्या से मेल खाते हैं जिसके बाद फिर से सीमांकक खुलता है।

कॉलबैक फ़ंक्शन स्ट्रिंग / वर्ण शाब्दिक लेता है और इसे सूची के पीछे धकेलता है l। इसके बाद चरित्र कोड 192 ( À) के साथ शुरू होने वाले चरित्र को लौटाता है और प्रत्येक शाब्दिक के साथ बढ़ता जाता है। इस प्रकार, कोड को इस तरह बदल दिया जाता है:

printf("%c", '\'');

printf(À, Á);

इन प्रतिस्थापन पात्रों को स्रोत कोड में नहीं होने की गारंटी दी जाती है, जिसका अर्थ है कि हम बाद में उन्हें स्पष्ट रूप से बैक-स्थानापन्न कर सकते हैं।

टिप्पणियाँ

`//.*`

x

रेगेक्स //प्लस सब कुछ न्यूलाइन से मेल खाता है और इसके साथ प्रतिस्थापित करता है x(खाली स्ट्रिंग के लिए पूर्व निर्धारित)।

प्रीप्रोसेसर निर्देश

`#.*`

_WR'¶

पाउंड साइन के साथ शुरू होने वाली नॉन-न्यूलाइन अक्षरों की रैप्स

रिक्त स्थान जिन्हें समाप्त नहीं किया जाना चाहिए

{
 (
  X*a J w.`(?=`
 ) . ')
}
M
[
 A`\w` RL 2
 "++"
 "--"
 "/*"
]

{
 a R w '·
}

यहां बहुत कुछ हो रहा है। पहला भाग रीगेक्स की इस सूची को बदलने के लिए बनाता है:

[
 `(?a)\w\s+(?=(?a)\w)`  Whitespace surrounded by [a-zA-Z_]
 `\+\s+(?=\+)`          Whitespace surrounded by +
 `\-\s+(?=\-)`          Whitespace surrounded by -
 `\/\s+(?=\*)`          Whitespace surrounded by / *
]

नोट lookaheads के उपयोग के उदाहरण के लिए, मैच के लिए, बस e में define P printf। इस तरह यह मैच उपभोग नहीं करता है P, जिसका अर्थ है कि अगला मैच इसका उपयोग कर सकता है।

हम किसी फ़ंक्शन को किसी सूची में मैप करके रीगेक्स की इस सूची को उत्पन्न करते हैं, जहां सूची में शामिल है

[
 [`(?a)\w` `(?a)\w`]
 "++"
 "--"
 "/*"
]

और फ़ंक्शन प्रत्येक तत्व के लिए ऐसा करता है:

(X*aJw.`(?=`).')
 X*a              Map unary X to elements/chars a: converts to regex, escaping as needed
                  Regexes like `\w` stay unchanged; strings like "+" become `\+`
    J             Join the resulting list on:
     w             Preset variable for `\s+`
      .`(?=`       plus the beginning of the lookahead syntax
(           ).')  Concatenate the closing paren of the lookahead

एक बार जब हम अपने regexes, हम इस कॉलबैक समारोह के साथ उनकी घटनाओं की जगह:

{aRw'·}

जो प्रत्येक मैच में व्हॉट्सएप चलाने की जगह लेता है ·

व्हॉट्सएप का खात्मा और सफाई

[w `¶+` '·]

[x n s]

wखाली स्ट्रिंग ( x), न्यूलाइन के लिए और ·अंतरिक्ष के लिए तीन नियमित प्रतिस्थापन व्हॉट्सएप के शेष रन ( ) ।

स्ट्रिंग और चरित्र शाब्दिक का बैक-प्रतिस्थापन

C(192+,#l)

l

हम उन सभी पात्रों की एक सूची का निर्माण करते हैं, जिन्हें हम अक्षर के लिए 192 + range(len(l))रूपांतरित करके और परिवर्तित करके अक्षर के लिए उपयोग करते हैं। हम इनमें से प्रत्येक को इसके संबद्ध शाब्दिक के साथ बदल सकते हैं l

और बस! परिणामी स्ट्रिंग को ऑटोप्रिंट किया गया है।


महान, मैं प्रभावित हूँ (+1)! //अंदर एक स्ट्रिंग शाब्दिक सहित एक निश्चित रूप से एक परीक्षण के मामले के लिए एक अच्छा विचार है, मैं एक कल जोड़ूंगा।
फेलिक्स पालमेन

उह ... अब मुझे यहां एक सूक्ष्म बग भी मिला ...
फेलिक्स पालमेन

मैं 14 दिनों (अगले सप्ताह के अंत) के बाद एक विजेता चुनने जा रहा हूं और यदि आप इस बग को ठीक करने का समय पाते हैं तो आपका समाधान पहला उम्मीदवार होगा । अभी, आपके पास सबसे कम स्कोर है :)
फेलिक्स पालमेन

1
@FelixPalmen फिक्स्ड!
19

7

हास्केल , 327 360 418 394 बाइट्स

g.(m.w.r.r=<<).lines.f
n:c:z="\n#_0123456789"++['A'..'Z']++['a'..'z']
(!)x=elem x
f('\\':'\n':a)=f a
f(a:b)=a:f b
f a=a
m('#':a)=c:a++[n]
m a=a
g(a:'#':b)=a:[n|a/=n]++c:g b
g(a:b)=a:g b
g a=a
s=span(!" \t")
r=reverse.snd.s
l n(a:b)d|a==d,n=a:w(snd$s b)|1>0=a:l(not$n&&a=='\\')b d
w('/':'/':_)=[]
w(a:b)|a!"\"'"=a:l(1>0)b a|(p,q:u)<-s b=a:[' '|p>"",a!z&&q!z||[a,q]!words"++ -- /*"]++w(q:u)
w a=a

इसे ऑनलाइन आज़माएं!

यह लिखने में बहुत मज़ा आया! पहले fफ़ंक्शन के माध्यम से आता है और लाइनों के अंत में सभी बैकस्लैश को हटा देता है और फिर linesइसे नए सिरे पर तार की सूची में तोड़ देता है। फिर हम लाइनों पर फ़ंक्शन का एक गुच्छा मैप करते हैं और उन सभी को वापस एक साथ जोड़ते हैं। वे कार्य: बाईं ओर से व्हाट्सएप ( t) और दाएं से ( r.t.rजहां rहै reverse); बीच से व्हाट्सएप को हटा दें, स्ट्रिंग और चरित्र शाब्दिक के साथ-साथ टिप्पणियों ( w) को हटा दें ; और अंत में एक नई पंक्ति जोड़ता है यदि पंक्ति # के साथ शुरू होती है। सभी लाइनों को एक साथ वापस लाने के बाद g# वर्णों की तलाश होती है और यह सुनिश्चित करता है कि वे एक नई रेखा से पहले हैं।

wथोड़ा जटिल है इसलिए मैं इसे आगे समझाऊंगा। पहले मैं "//" की जांच करता हूं क्योंकि wमुझे पता है कि मैं एक स्ट्रिंग शाब्दिक में नहीं हूं मुझे पता है कि यह एक टिप्पणी है इसलिए मैं बाकी की रेखा को छोड़ देता हूं। अगला मैं जांचता हूं कि क्या सिर एक स्ट्रिंग या चरित्र शाब्दिक के लिए सीमांकक है। यदि यह मैं है, तो इसे प्रिपेंड करें और lपात्रों के माध्यम से चलने वाले बैटन को पास करें , "एस्केप" स्थिति पर नज़र रखना, nजिसके साथ यदि लगातार स्लैश की संख्या भी हुई है तो यह सच होगा। जब lएक सीमांकक का पता लगाता है और भागने की स्थिति में नहीं होता है, तो यह बैटन को वापस करता है w, शाब्दिक के बाद व्हॉट्सएप को समाप्त करने के लिए ट्रिमिंग wकरता है क्योंकि पहले चरित्र को व्हाट्सएप नहीं होने की उम्मीद है। कबwपूंछ में व्हॉट्सएप देखने के लिए स्पैनिटर का उपयोग नहीं करता है। यदि कोई है तो यह जांचता है कि क्या इसके आसपास के पात्रों को संपर्क में नहीं लाया जा सकता है और यदि ऐसा है तो एक स्थान सम्मिलित करता है। फिर यह व्हाट्सएप के खत्म होने के बाद फिर से बन जाता है। यदि कोई व्हाट्सएप नहीं होता है तो कोई स्थान नहीं डाला जाता है और यह वैसे भी चलता रहता है।

संपादित करें: मेरे कार्यक्रम में एक बग को इंगित करने के लिए @DLosc के लिए बहुत बहुत धन्यवाद जो वास्तव में मेरे लिए एक रास्ता था, साथ ही साथ इसे छोटा करने के लिए! पैटर्न मिलान के लिए हुर्रे!

EDIT2: मैं एक बेवकूफ हूँ जो कल्पना को पूरा नहीं करता है! फिर से धन्यवाद कि बाहर इशारा करने के लिए DLosc!

EDIT3: बस कुछ कष्टप्रद प्रकार की कमी की बात पर ध्यान दिया , जो किसी कारण से बदल e=elemगया Char->[Char]->Bool, इस प्रकार टूट गया e[a,q]। मुझे इसे सही होने के लिए मजबूर करने के लिए एक प्रकार का हस्ताक्षर जोड़ना पड़ा। क्या किसी को पता है कि मैं इसे कैसे ठीक कर सकता हूं? मैंने हास्केल में पहले कभी यह समस्या नहीं की है। TIO

EDIT4: बग @FelixPalmen के लिए त्वरित सुधार ने मुझे दिखाया। मैं बाद में इसे नीचे करने की कोशिश कर सकता हूं जब मेरे पास कुछ समय होगा।

EDIT5: -24 बाइट्स @Lynn को धन्यवाद! धन्यवाद! मुझे नहीं पता था कि आप पैटर्न के उपयोग से वैश्विक दायरे में चीजों को असाइन कर सकते हैं जैसे n:c:z=...कि वास्तव में अच्छा है! यह भी अच्छा विचार है elemकि मैं इसके बारे में सोचना चाहता हूँ के लिए एक ऑपरेटर बना रही है।



2
आप खूंखार मोनोमोर्फिज्म प्रतिबंध में भाग रहे हैं ; परिभाषित करना e x y=elem x y(या यहां तक ​​कि e x=elem x) आपकी समस्या को हल करता है। (मैंने eएक ऑपरेटर का नाम बदल दिया (!)।)
लिन

3

सी, 497 494 490 489 बाइट्स

जब से हम C प्रोसेस कर रहे हैं, चलो C का उपयोग करते हैं ! फ़ंक्शन f()पॉइंटर पॉइंटर से pआउटपुट लेता है और पॉइंटर को आउटपुट देता है q, और मानता है कि इनपुट ASCII में है:

#define O*q++
#define R (r=*p++)
#define V(c)(isalnum(c)||c==95)
char*p,*q,r,s,t;d(){isspace(r)?g():r==47&&*p==r?c(),g():r==92?e():(O=s=r)==34?b():r==39?O=R,a():r?a():(O=r);}a(){R;d();}b(){((O=R)==34?a:r==92?O=R,b:b)();}c(){while(R-10)p+=r==92;}e(){R-10?s=O=92,O=r,a():h();}j(){(!isspace(R)?r==47&&*p==r?c(),j:(t=r==35,d):j)();}f(){t=*p==35;j();}i(){V(s)&&V(r)||s==47&&r==42||(s==43||s==45)&&r==s&&*p==s?O=32:0;d();}h(){isspace(R)?g():i();}g(){(r==10?t?O=r,j:*p==35?s-10?s=O=r,j:0:h:h)();}

हम मानते हैं कि फ़ाइल अच्छी तरह से बनाई गई है - स्ट्रिंग और चरित्र शाब्दिक बंद हैं, और यदि अंतिम पंक्ति पर एक टिप्पणी है, तो इसे बंद करने के लिए एक नई रेखा होनी चाहिए।

व्याख्या

पूर्व-गोल्फ संस्करण केवल थोड़ा अधिक सुपाठ्य है, मुझे डर है:

#define O *q++=
#define R (r=*p++)
#define V(c)(isalnum(c)||c=='_')
char*p,*q,r,s,t;
d(){isspace(r)?g():r=='/'&&*p==r?c(),g():r=='\\'?e():(O s=r)=='"'?b():r=='\''?O R,a():r?a():(O r);}
a(){R;d();}
b(){((O R)=='"'?a:r=='\\'?O R,b:b)();}
c(){while(R!='\n')p+=r=='\\';}
e(){R!='\n'?s=O'\\',O r,a():h();}
j(){(!isspace(R)?r=='/'&&*p==r?c(),j:(t=r=='#',d):j)();}
f(){t=*p=='#';j();}
i(){V(s)&&V(r)||s=='/'&&r=='*'||(s=='+'||s=='-')&&r==s&&*p==s?O' ':0;d();}
h(){isspace(R)?g():i();}
g(){(r=='\n'?t?O r,j:*p=='#'?s!='\n'?s=O r,j:0:h:h)();}

यह पूंछ पुनरावृत्ति द्वारा एक राज्य मशीन को लागू करता है। सहायक मैक्रोज़ और चर हैं

  • Oके लिए utput
  • Rके आर में EAD इनपुटr
  • Vनिर्धारित करने के लिए वी alid पहचानकर्ता, वर्णों (के बाद से !isalnum('_'))
  • pऔर q- मैं / ओ संकेत के रूप में वर्णित है
  • r- अंतिम चरित्र r ead होना
  • s- एस aved हाल में गैर-सफ़ेद चरित्र
  • t- टी एजी जब एक पूर्वप्रक्रमक निर्देश पर काम कर रहा

हमारे राज्य हैं

  • a() - सामान्य सी कोड
  • b() - शाब्दिक स्ट्रिंग
  • c() - टिप्पणी
  • d() - सामान्य सी कोड, पढ़ने के बाद r
  • e() - निकास का क्रम
  • f() - प्रारंभिक अवस्था (मुख्य कार्य)
  • g() - व्हाट्सएप में
  • h()खाली स्थान के में - प्रेषण के लिए - g()याi()
  • i() - व्हाट्सएप के तुरंत बाद - क्या हमें स्पेस कैरेक्टर डालने की जरूरत है?
  • j() - शुरुआती व्हाट्सएप - कभी भी स्पेस कैरेक्टर न डालें

परीक्षण कार्यक्रम

#define DEMO(code)                              \
    do {                                        \
        char in[] = code;                       \
        char out[sizeof in];                    \
        p=in;q=out;f();                         \
        puts("vvvvvvvvvv");                     \
        puts(out);                              \
        puts("^^^^^^^^^^");                     \
    } while (0)

#include<stdio.h>
#include<stdlib.h>
int main()
{
    DEMO(
         "main() {\n"
         "    printf(\"Hello, World!\"); // hi\n"
         "}\n"
         );
    DEMO(
         "#define max(x, y)                               \\\n"
         "    x > y ? x : y\n"
         "#define I(x) scanf(\"%d\", &x)\n"
         "a;\n"
         "b; // just a needless comment, \\\n"
         "        because we can!\n"
         "main()\n"
         "{\n"
         "    I(a);\n"
         "    I(b);\n"
         "    printf(\"\\\" max \\\": %d\\n\", max(a, b));\n"
         "}\n"
         );
    DEMO(
         "x[10];*c;i;\n"
         "main()\n"
         "{\n"
         "    int _e;\n"
         "    for(; scanf(\"%d\", &x) > 0 && ++_e;);\n"
         "    for(c = x + _e; c --> x; i = 100 / *x, printf(\"%d \", i - --_e));\n"
         "}\n"
         );
    DEMO(
         "// often used functions/keywords:\n"
         "#define P printf(\n"
         "#define A case\n"
         "#define B break\n"
         "\n"
         "// loops for copying rows upwards/downwards are similar -> macro\n"
         "#define L(i, e, t, f, s) \\\n"
         "        for (o=i; o e;){ strcpy(l[o t], l[o f]); c[o t]=c[s o]; }\n"
         "\n"
         "// range check for rows/columns is similar -> macro\n"
         "#define R(m,o) { return b<1|b>m ? m o : b; }\n"
         "\n"
         "// checking for numerical input is needed twice (move and print command):\n"
         "#define N(f) sscanf(f, \"%d,%d\", &i, &j) || sscanf(f, \",%d\", &j)\n"
         "\n"
         "// room for 999 rows with each 999 cols (not specified, should be enough)\n"
         "// also declare \"current line pointers\" (*L for data, *C for line length),\n"
         "// an input buffer (a) and scratch variables\n"
         "r, i, j, o, z, c[999], *C, x=1, y=1;\n"
         "char a[999], l[999][999], (*L)[999];\n"
         "\n"
         "// move rows down from current cursor position\n"
         "D()\n"
         "{\n"
         "    L(r, >y, , -1, --)\n"
         "    r++ ? strcpy(l[o], l[o-1]+--x), c[o-1]=x, l[o-1][x]=0 : 0;\n"
         "    c[y++] = strlen(l[o]);\n"
         "    x=1;\n"
         "}\n"
         "\n"
         "// move rows up, appending uppermost to current line\n"
         "U()\n"
         "{\n"
         "    strcat(*L, l[y]);\n"
         "    *C = strlen(*L);\n"
         "    L(y+1, <r, -1, , ++)\n"
         "    --r;\n"
         "    *l[r] = c[r] = 0;\n"
         "}\n"
         "\n"
         "// normalize positions, treat 0 as max\n"
         "X(b) R(c[y-1], +1)\n"
         "Y(b) R(r, )\n"
         "\n"
         "main()\n"
         "{\n"
         "    for(;;) // forever\n"
         "    {\n"
         "        // initialize z as current line index, the current line pointers,\n"
         "        // i and j for default values of positioning\n"
         "        z = i = y;\n"
         "        L = l + --z;\n"
         "        C = c + z;\n"
         "        j = x;\n"
         "\n"
         "        // prompt:\n"
         "        !r || y/r && x > *C\n"
         "            ? P \"end> \")\n"
         "            : P \"%d,%d> \", y, x);\n"
         "\n"
         "        // read a line of input (using scanf so we don't need an include)\n"
         "        scanf(\"%[^\\n]%*c\", a)\n"
         "\n"
         "            // no command arguments -> make check easier:\n"
         "            ? a[2] *= !!a[1],\n"
         "\n"
         "            // numerical input -> have move command:\n"
         "            // calculate new coordinates, checking for \"relative\"\n"
         "            N(a)\n"
         "                ? y = Y(i + (i<0 | *a=='+') * y)\n"
         "                    , x = X(j + (j<0 || strchr(a+1, '+')) * x)\n"
         "                :0\n"
         "\n"
         "            // check for empty input, read single newline\n"
         "            // and perform <return> command:\n"
         "            : ( *a = D(), scanf(\"%*c\") );\n"
         "\n"
         "        switch(*a)\n"
         "        {\n"
         "            A 'e':\n"
         "                y = r;\n"
         "                x = c[r-1] + 1;\n"
         "                B;\n"
         "\n"
         "            A 'b':\n"
         "                y = 1;\n"
         "                x = 1;\n"
         "                B;\n"
         "\n"
         "            A 'L':\n"
         "                for(o = y-4; ++o < y+2;)\n"
         "                    o<0 ^ o<r && P \"%c%s\\n\", o^z ? ' ' : '>', l[o]);\n"
         "                for(o = x+1; --o;)\n"
         "                    P \" \");\n"
         "                P \"^\\n\");\n"
         "                B;\n"
         "\n"
         "            A 'l':\n"
         "                puts(*L);\n"
         "                B;\n"
         "\n"
         "            A 'p':\n"
         "                i = 1;\n"
         "                j = 0;\n"
         "                N(a+2);\n"
         "                for(o = Y(i)-1; o<Y(j); ++o)\n"
         "                    puts(l[o]);\n"
         "                B;\n"
         "\n"
         "            A 'A':\n"
         "                y = r++;\n"
         "                strcpy(l[y], a+2);\n"
         "                x = c[y] = strlen(a+2);\n"
         "                ++x;\n"
         "                ++y;\n"
         "                B;\n"
         "\n"
         "            A 'i':\n"
         "                D();\n"
         "                --y;\n"
         "                x=X(0);\n"
         "                // Commands i and r are very similar -> fall through\n"
         "                // from i to r after moving rows down and setting\n"
         "                // position at end of line:\n"
         "\n"
         "            A 'r':\n"
         "                strcpy(*L+x-1, a+2);\n"
         "                *C = strlen(*L);\n"
         "                x = 1;\n"
         "                ++y > r && ++r;\n"
         "                B;\n"
         "\n"
         "            A 'I':\n"
         "                o = strlen(a+2);\n"
         "                memmove(*L+x+o-1, *L+x-1, *C-x+1);\n"
         "                *C += o;\n"
         "                memcpy(*L+x-1, a+2, o);\n"
         "                x += o;\n"
         "                B;\n"
         "\n"
         "            A 'd':\n"
         "                **L ? **L = *C = 0, x = 1 : U();\n"
         "                y = y>r ? r : y;\n"
         "                B;\n"
         "\n"
         "            A 'j':\n"
         "                y<r && U();\n"
         "        }\n"
         "    }\n"
         "}\n";);
}

यह पैदा करता है

main(){printf("Hello, World!");}
#define max(x,y)x>y?x:y
#define I(x)scanf("%d",&x)
a;b;main(){I(a);I(b);printf("\" max \": %d\n",max(a,b));}
x[10];*c;i;main(){int _e;for(;scanf("%d",&x)>0&&++_e;);for(c=x+_e;c-->x;i=100/ *x,printf("%d ",i- --_e));}
#define P printf(
#define A case
#define B break
#define L(i,e,t,f,s)for(o=i;o e;){strcpy(l[o t],l[o f]);c[o t]=c[s o];}
#define R(m,o){return b<1|b>m?m o:b;}
#define N(f)sscanf(f,"%d,%d",&i,&j)||sscanf(f,",%d",&j)
r,i,j,o,z,c[999],*C,x=1,y=1;char a[999],l[999][999],(*L)[999];D(){L(r,>y,,-1,--)r++?strcpy(l[o],l[o-1]+--x),c[o-1]=x,l[o-1][x]=0:0;c[y++]=strlen(l[o]);x=1;}U(){strcat(*L,l[y]);*C=strlen(*L);L(y+1,<r,-1,,++)--r;*l[r]=c[r]=0;}X(b)R(c[y-1],+1)Y(b)R(r,)main(){for(;;){z=i=y;L=l+--z;C=c+z;j=x;!r||y/r&&x>*C?P"end> "):P"%d,%d> ",y,x);scanf("%[^\n]%*c",a)?a[2]*=!!a[1],N(a)?y=Y(i+(i<0|*a=='+')*y),x=X(j+(j<0||strchr(a+1,'+'))*x):0:(*a=D(),scanf("%*c"));switch(*a){A'e':y=r;x=c[r-1]+1;B;A'b':y=1;x=1;B;A'L':for(o=y-4;++o<y+2;)o<0^o<r&&P"%c%s\n",o^z?' ' :'>',l[o]);for(o=x+1;--o;)P" ");P"^\n");B;A'l':puts(*L);B;A'p':i=1;j=0;N(a+2);for(o=Y(i)-1;o<Y(j);++o)puts(l[o]);B;A'A':y=r++;strcpy(l[y],a+2);x=c[y]=strlen(a+2);++x;++y;B;A'i':D();--y;x=X(0);A'r':strcpy(*L+x-1,a+2);*C=strlen(*L);x=1;++y>r&&++r;B;A'I':o=strlen(a+2);memmove(*L+x+o-1,*L+x-1,*C-x+1);*C+=o;memcpy(*L+x-1,a+2,o);x+=o;B;A'd':**L?**L=*C=0,x=1:U();y=y>r?r:y;B;A'j':y<r&&U();}}}

सीमा

इससे परिभाषाएं टूट जाती हैं

#define A (x)

अंतरिक्ष को हटाकर जो नाम को विस्तार से अलग करता है, दे रहा है

#define A(x)

पूरी तरह से अलग अर्थ के साथ। यह मामला परीक्षण सेट से अनुपस्थित है, इसलिए मैं इसे संबोधित नहीं करने जा रहा हूं।

मुझे संदेह है कि मैं एक बहु-पास इन-प्लेस रूपांतरण के साथ एक छोटा संस्करण तैयार करने में सक्षम हो सकता हूं - मैं अगले सप्ताह कोशिश कर सकता हूं।


आप =की परिभाषा के अंत में एक बाइट को हटाकर उस स्थान को Oबदल सकते हैं जो प्रत्येक कॉल का अनुसरण करता Oहै =
Zacharý

यह बहुत अच्छा है;) "सीमा" के बारे में, प्रश्न पर मेरी टिप्पणी को भी देखें - यह पता लगाने से इसमें बहुत अधिक जटिलता होगी।
फेलिक्स पालमेन

@Zachary - इसके लिए धन्यवाद - मैं भूल गया जब मैंने सामान्य कोड को ASCII- विशिष्ट में बदल दिया O'\\'और O' 'दोनों ने एक स्थान हासिल कर लिया।
टोबे स्पाइट


2

सी,  705   663  640 बाइट्स

@ 40 बाइट गोल्फिंग के लिए @ ज़ाचार्जी को और 23 बाइट गोल्फिंग के लिए @ नाहुएल फौइलुल को धन्यवाद!

#define A(x)(x>47&x<58|x>64&x<91|x>96&x<123)
#define K if(*C==47&(C[1]==47|p==47)){if(p==47)--G;for(c=1;c;*C++-92||c++)*C-10||--c;if(d)p=*G++=10,--d;
#define D if(!d&*C==35){d=1;if(p&p-10)p=*G++=10;}
#define S K}if((A(p)&A(*C))|(p==*C&l==43|p==45)|p==47&*C==42|p==95&(A(*C)|*C==95)|*C==95&(A(p)|p==95))p=*G++=32;}
#define W*C<33|*C==92
#define F{for(;W;C++)
c,d,e,p,l;g(char*C,char*G)F;for(;*C;*C>32&&*C-34&&*C-39&&(p=*G++=*C),*C-34&&*C-39&&C++){l=e=0;if(*C==34)l=34;if(*C==39)l=39;if(l)for(*G++=l,p=*G++=*++C;*C++-l|e%2;e=*(C-1)-92?0:e+1)p=*G++=*C;K}D if(d){if(W)F{*C-92||++d;*C-10||--d;if(!d){p=*G++=10;goto E;}}S}else{if(W)F;S}E:D}*G=0;}

इसे ऑनलाइन आज़माएं!


for(;W;C++){}बन सकता है for(;W;C++);?
Zacharý

@ Zacharý कि कभी नहीं पूछा गया था। यह बहुत अंतिम चरण के लिए एक कब्र है: निरर्थक व्हाट्सएप और टिप्पणियों को हटा दें।
फेलिक्स पालमेन 15

मैं उनके कोड का जिक्र कर रहा था, चुनौती का नहीं।
Zacharý

@ Zacharý haha ​​मैं देख रहा हूँ ... अजीब जब कोड और इनपुट एक ही भाषा हैं?)
फेलिक्स पाम्स

क्या यह 665 बाइट्स के लिए काम करेगा? goo.gl/E6tk8V
Zacharý

2

पर्ल 5, 250 + 3 (-00 एन) , 167 + 1 (-पी) बाइट्स

$_.=<>while s/\\
//;s,(//.*)|(("|')(\\.|.)*?\3)|/?[^"'/]+,$1|$2?$2:$&=~s@(\S?)\K\s+(?=(.?))@"$1$2"=~/\w\w|\+\+|--|\/\*/&&$"@ger,ge;$d++&&$l+/^#/&&s/^/
/,$l=/^#/m if/./

इसे ऑनलाइन आज़माएं


हां, मैं सिर्फ गैर-इष्टतम समाधान करता हूं। मैंने अभी अभी tio लिंक जोड़ा है, जब मेरे पास समय होगा तो मैं इसे देखूंगा।
नहुएल फौलीउल

प्रीप्रोसेसर निर्देश अपनी स्वयं की लाइन पर होते हैं जब कोड से पहले रखा जाता है, जैसा कि परीक्षण के मामलों में है, लेकिन अगर यह आवश्यक है तो मैं बदलाव
जोड़ूंगा

1
फिक्स्ड अपडेट देखें
नाहुएल फौइलुल

0

पायथन 2 , 479 456 445 434 502 497 बाइट्स

e=enumerate
import re
u=re.sub
def f(s):
 r=()
 for l in u(r'\\\n','',s).split('\n'):
	s=p=w=0;L=[]
	for i,c in e(l):
	 if(p<1)*'//'==l[i:i+2]:l=l[:i]
	 if c in"'\""and w%2<1:
		if p in(c,0):L+=[l[s:i+1]];s=i+1
		p=[0,c][p<1]
	 w=[0,w+1]['\\'==c]
	r+=L+[l[s:]],
 S=''
 for l in r:s=''.join([u('. .',R,u('. .',R,u('\s+',' ',x))).strip(),x][i%2]for i,x in e(l));S+=['%s','\n%s\n'][s[:1]=='#']%s
 print u('\n\n','\n',S).strip()
def R(m):g=m.group(0);f=g[::2];return[f,g][f.isalnum()or f in'++ -- /*']

इसे ऑनलाइन आज़माएं!

संपादित करें: फिक्स्ड शामिल करने के लिए - -, + +और/ *

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