私の「ゴルフ前」のゴルフC


12

バックグラウンド

私の場合は Cでの提出、私は処理ツールを必要としています。他の多くの言語と同様に、空白はCソースではほとんど関係ありません(常にではありません!)-それでもコードは人間にとってはるかにわかりやすいものになります。単一の冗長な空白を含まない完全にゴルフされたCプログラムは、ほとんど読み込めません。

そのため、空白やコメントを含む提出のためにCでコードを書くのが好きなので、プログラムは書き込み中にわかりやすい構造を保ちます。最後のステップは、すべてのコメントと余分な空白を削除することです。これは退屈で心のない作業であり、コンピュータープログラムのインターンが実際に行う必要があります。

仕事

次の規則に従って、「事前ゴルフ」されたCソースからコメントと冗長な空白を削除するプログラムまたは関数を作成します。

  • \行の最後の文字として(バックスラッシュ)がある行継続。これを見つけた場合は、次の行を同じ論理行の一部として扱う必要があります(たとえば、他の操作を行う前に、\および次の行\n(改行)を完全に削除できます)。
  • コメントは、で始まる1行形式のみを使用し//ます。したがって、それらを削除するには//文字列リテラルの外側で遭遇する論理行の残りを無視します(以下を参照)。
  • 空白文字は(スペース)、\t(タブ)および\n(改行なので、ここでは論理行の終わりです)。
  • 空白のシーケンスを見つけたら、その周囲の空白以外の文字を調べます。もし

    • 両方とも英数字またはアンダースコア(範囲[a-zA-Z0-9_])または
    • 両方とも +
    • 両方とも -
    • 前のものは/、次のものは*

    次に、シーケンスを単一のスペース()文字にます。

    それ以外の場合は、シーケンスを完全に削除します。

    このルールにはいくつかの例外あります

    • プリプロセッサディレクティブは、出力の独自の行に表示する必要があります。プリプロセッサディレクティブは、次で始まる行です#です。
    • 文字列リテラルまたは文字リテラル内では、空白を削除しないでください。任意の"(二重引用符)/ '直接バックスラッシュの奇数が付け加えていません(単一引用符)は、( \)が開始または終了する文字列リテラル / 文字リテラルを。文字列と文字リテラルは、それらが開始した同じ行で終了することが保証されています。文字列リテラル文字リテラルはので、入れ子にすることができない'内部の文字列リテラルと同様に、"内部の文字はリテラル特別な意味を持っていません。

I / O仕様

入力と出力は、改行文字を含む文字シーケンス(文字列)、または改行文字を含まない文字列の配列/リストのいずれかでなければなりません。配列/リストの使用を選択した場合、各要素は行を表すため、改行は暗黙的です各要素の後にに追加されます。

入力は有効なCプログラムのソースコードであると想定できます。これは、印刷可能な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

PIP148の 135 133 138バイト

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

バイトはCP-1252でカウントされるため·それぞれ1バイトです。これは、Cコードを単一のコマンドライン引数として想定していることに注意してください。実際のコマンドラインでは、多数のエスケープシーケンスを使用する必要があります。オンライン試すのは簡単です!

わずかに未使用のバージョンの説明

このコードは、いくつかのトリックを使用して、一連の置換操作を実行します。

バックスラッシュの継続

私たちは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 / *
]

先読みを使用して、たとえばe in だけに一致することに注意してください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

正規表現を取得したら、それらの出現をこのコールバック関数に置き換えます。

{aRw'·}

これは、各一致の空白の実行をに置き換え·ます。

空白の除去とクリーンアップ

[w `¶+` '·]

[x n s]

連続する3つの置換はw、空文字列(x)、改行、および·スペースの代わりに、空白()の残りの実行を置き換えます。

文字列と文字リテラルの逆置換

C(192+,#l)

l

文字を取得192 + range(len(l))して文字に変換することにより、リテラルの置換として使用したすべての文字のリストを作成します。その後、これらのそれぞれをに関連付けられたリテラルに置き換えることができlます。

以上です!結果の文字列は自動印刷されます。


素晴らしい、感心しました(+1)!//文字列リテラルの中に文字列リテラルを含めることは、テストケースにとって間違いなく良い考えです。明日は追加します。
フェリックスパルメン

うーん...今、私は微妙なバグを見つけました ...ここにもを
フェリックスPalmen

14日後(来週の終わり)に勝者を選びます。あなたのソリューションが最初の候補になります。 。このバグを修正する時間があれば。今、あなたは最低のスコアを持っています:)
フェリックスパルメン

1
@FelixPalmen修正済み!
DLosc

7

Haskell327 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.rwhere ris reverse)から空白を削除します; 文字列と文字リテラルを無視し、コメントを削除する(w); そして、行が#で始まる場合、最後に改行文字を追加します。すべての行が連結された後g、#文字を探して、改行の前にあることを確認します。

w少し複雑なので、さらに説明します。w文字列リテラルではないことを知っているので、これがコメントであることを知っているので、最初に「//」をチェックし、残りの行を削除します。次に、ヘッドが文字列または文字リテラルの区切り文字かどうかを確認します。場合は、先頭に追加lし、キャラクターを通過するバトンを渡し、n偶数個の連続したスラッシュがあった場合に真になる「エスケープ」状態を追跡します。l区切り文字を検出し、エスケープ状態ではない場合、バトンをに戻し、最初の文字が空白ではないことを期待するwため、リテラルの後の空白を削除するためにトリミングしwます。いつwspanを使用して末尾の空白を検索する区切り文字が見つかりません。何かがある場合は、周囲の文字に接触できないかどうかをチェックし、接触している場合はスペースを挿入します。その後、空白が終了した後に繰り返します。空白がない場合、スペースは挿入されず、とにかく移動します。

編集:実際に私もそれを短縮する方法につながった私のプログラムのバグを指摘してくれた@DLoscに感謝します!パターンマッチングに万歳!

EDIT2:私は仕様を読み終えていないばかです!それを指摘してくれたDLoscに再び感謝します!

EDIT3:ちょうどいくつかの迷惑なタイプ削減の事に気づいた e=elemChar->[Char]->Boolように壊し、何らかの理由をe[a,q]。タイプシグネチャを追加して、強制的に正しいものにする必要がありました。誰も私がそれを修正する方法を知っていますか?Haskellでこの問題が発生したことはありません。TIO

EDIT4:バグ@FelixPalmenのクイックフィックスが私に見せてくれました。後で時間があれば、ゴルフをしようと思うかもしれません。

EDIT5:@Lynnのおかげで-24バイト!ありがとうございました!このようなパターンマッチングを使用して、グローバルスコープで何かを割り当てることができるとは知りませn:c:z=...んでした!また、elem私はそれを考えていた希望のために演算子を作ることをお勧めします。



2
あなたは恐ろしい単相性の制限に直面しています; 定義e x y=elem x y(またはe x=elem x)することで問題を解決できます。(私eは演算子に名前を変更しました(!)。)
リン

3

C、497 494 490 489バイト

Cを処理しているので、C を使用して実行しましょう!関数f()は、charポインターから入力を受け取り、pointer 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以下のためのO utput
  • RRへの入力をEADr
  • V決定するV ALID識別子文字(以降!isalnum('_')
  • pおよびq-説明されているI / Oポインター
  • r-する最後の文字R EAD
  • s- 最近の非空白文字保存
  • t- プリプロセッサディレクティブで作業する場合はt ag

私たちの州は

  • a() -通常のCコード
  • b() -文字列リテラル
  • c() -コメント
  • d() -読み取り後の通常のCコード 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各呼び出しの後に続くスペースをOaに変更することで1バイトを節約できます=
ザカリー

これは素晴らしいです;)「制限」については、質問自体に対する私のコメントも参照してください- これを検出すると、あまりにも複雑になります。
フェリックスパルメン

@Zachary-そのおかげで-一般的なコードをASCII固有のものに変更しO'\\'O' '両方がスペースを取得したことを忘れました。
トビーSpeight


2

C、 705   663  640バイト

40バイトのゴルフをしてくれた@Zacharýと、23バイトのゴルフをしてくれた@Nahuel Fouilleulに感謝します!

#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ýhahaなるほど...コードと入力が同じ言語のときは奇妙です;)
フェリックス

これは665バイトで動作しますか?goo.gl/E6tk8V
ザカリー

2

Perl 5、250 + 3(-00n)、167 + 1(-p)バイト

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

オンラインで試す


はい、最適ではないソリューションを追加しました。Tioリンクを追加しました。時間があればゴルフを楽しみます。
ナウエルフイユル

テストケースのように、コードの前に配置されたプリプロセッサディレクティブは独自の行にありますが、必要な場合は変更を追加します
Nahuel Fouilleul

1
修正を参照してください
ナウエルフイユ

0

パイソン2479の 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'++ -- /*']

オンラインでお試しください!

編集:、、およびを含めるよう- -に修正+ +/ *

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.