태그 보관물: parsing

parsing

C 배열 확장 아이러니를 좋아하기 때문에 코드를 가능한 짧게

C 프로그래밍 언어에서 배열은 다음과 같이 정의됩니다.

int foo[] = {4, 8, 15, 16, 23, 42};      //Foo implicitly has a size of 6

배열의 크기는 초기화 요소 (이 경우 6)에서 추론됩니다. C 배열을 이런 식으로 작성하여 명시 적으로 크기를 지정한 다음 각 요소를 순서대로 정의 할 수도 있습니다.

int foo[6];        //Give the array an explicit size of 6
foo[0] = 4;
foo[1] = 8;
foo[2] = 15;
foo[3] = 16;
foo[4] = 23;
foo[5] = 42;

도전

첫 번째 방법에서 두 번째 방법으로 배열을 확장하는 프로그램 또는 함수를 작성해야합니다. 코드를 더 길게 만드는 프로그램을 작성하고 아이러니를 좋아하기 때문에 코드를 가능한 짧게 만들어야합니다.

입력은 원래 배열을 나타내는 문자열이되고 출력은 확장 된 배열 정의가됩니다. 입력이 항상 다음과 같다고 가정 할 수 있습니다.

<type> <array_name>[] = {<int>, <int>, <int> ... };

“Type”과 “array_name”은 모두 알파벳 문자와 밑줄로 구성 _됩니다. 목록의 요소는 항상 -2,147,483,648에서 2,147,483,647 범위의 숫자입니다. 다른 형식의 입력은 처리 할 필요가 없습니다.

후행 줄 바꿈이 허용되지만 출력의 공백은 테스트 출력의 공백과 정확하게 일치해야합니다.

IO 테스트 :

#in
short array[] = {4, 3, 2, 1};

#out
short array[4];
array[0] = 4;
array[1] = 3;
array[2] = 2;
array[3] = 1;


#in
spam EGGS[] = {42};

#out
spam EGGS[1];
EGGS[0] = 42;


#in
terrible_long_type_name awful_array_name[] = {7, -8, 1337, 0, 13};

#out
terrible_long_type_name awful_array_name[5];
awful_array_name[0] = 7;
awful_array_name[1] = -8;
awful_array_name[2] = 1337;
awful_array_name[3] = 0;
awful_array_name[4] = 13;

모든 언어의 제출은 권장하지만, 보너스 포인트 당신은 그것을 할 수있는 경우 C.

리더 보드 :

다음은 최고의 답변을 보여주는 리더 보드입니다.

var QUESTION_ID=77857,OVERRIDE_USER=31716;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>


답변

Pyth, 44 바이트

++Khcz\]lJ:z"-?\d+"1"];"VJs[ecKd~hZ"] = "N\;

테스트 스위트

정규 표현식 및 문자열 자르기 특히 영리하지는 않습니다.

설명:

++Khcz\]lJ:z"-?\d+"1"];"VJs[ecKd~hZ"] = "N\;
                                                Implicit: z = input()
    cz\]                                        Chop z on ']'
   h                                            Take string before the ']'
  K                                             Store it in K
 +                                              Add to that
         :z"-?\d+"1                             Find all numbers in the input
        J                                       Store them in J
       l                                        Take its length.
+                  "];"                         Add on "];" and print.
                       VJ                       For N in J:
                         s[                     Print the following, concatenated:
                            cKd                 Chop K on spaces.
                           e                    Take the last piece (array name)
                               ~hZ              The current interation number
                                  "] = "        That string
                                        N       The number from the input
                                         \;     And the trailing semicolon.

답변

Vim, 54, 52, 49 47 키 스트로크


2wa0<esc>qqYp<c-a>6ldf @qq@q$dT]dd:%norm dwf{xwC;<CR>gg"0P

설명:

2wa0<esc>                     'Move 2 words forward, and insert a 0.
         qq                   'Start recording in register Q
           Yp                 'Duplicate the line
             <c-a>6l          'Increment the next number then move 6 spaces right
                    df        'Delete until the next space
                       @qq@q  'Recursively call this macro

이제 버퍼는 다음과 같습니다 :

int foo[0] = {4, 8, 15, 16, 23, 42};
int foo[1] = {8, 15, 16, 23, 42};
int foo[2] = {15, 16, 23, 42};
int foo[3] = {16, 23, 42};
int foo[4] = {23, 42};
int foo[5] = {42};
int foo[6] = {42};

커서가 마지막 줄에 있습니다.

후반 :

$                           'Move to the end of the line
 dT]                        'Delete back until we hit a ']'
    dd                      'Delete this whole line.
      :%norm         <CR>   'Apply the following keystrokes to every line:
             dw             'Delete a word (in this case "int")
               f{x          '(f)ind the next '{', then delete it.
                  wC;       'Move a word, then (C)hange to the end of this line,
                            'and enter a ';'

이제 모든 것이 좋아 보이므로 원래 배열 선언을 추가하면됩니다. 그래서 우리는 :

gg        'Move to line one
  "0P     'Print buffer '0' behind us. Buffer '0' always holds the last deleted line,
          'Which in this case is "int foo[6];"

답변

망막 (108) 104 (100) 69 바이트

바이트 수는 ISO 8859-1 인코딩을 가정합니다.

].+{((\S+ ?)+)
$#2];$1
+`((\w+\[).+;(\S+ )*)(-?\d+).+
$1¶$2$#3] = $4;

PowerShell, 이길 …

코드 설명

첫 줄: ].+{((\S+ ?)+)

먼저 유형, 배열 이름 및 여는 괄호 (바이트 저장)를 유지해야하므로 일치하지 않습니다. 따라서 닫는 대괄호, 문자 수 및 여는 중괄호 :와 일치합니다 ].+{. 그런 다음 숫자 목록과 일치시킵니다. 내가 지금까지 찾은 가장 짧은 것은 다음과 같습니다 ((\S+ ?)+). 공백이 아닌 문자 (숫자, 음수 부호 및 쉼표 포함)와 일치하고 공백이있을 수 있습니다 \S+ ?. 그런 다음이 문자 그룹을 필요한만큼 여러 번 반복 (\S+ ?)+하여 큰 캡처 그룹에 넣습니다. 닫는 중괄호 또는 세미콜론과 일치하지 않습니다. 세 번째 줄 설명이 그 이유를 알려줍니다.

두 번째 줄 : $#2];$1

입력의 일부만 일치했기 때문에 일치하지 않는 부분은 여전히 ​​존재합니다. 따라서 일치하지 않는 여는 대괄호 뒤에 목록의 길이를 넣습니다 $#2. replace 수정자는 #특정 캡처 그룹이 만든 일치 수를 제공하므로 도움이됩니다. 이 경우 캡처 그룹 2. 그런 다음 닫는 괄호와 세미콜론을 넣고 마지막으로 전체 목록을 작성합니다.

input short array[] = {4, 3, 2, 1};을 사용한 경우이 교체 후의 내부 표현은 다음과 같습니다.

짧은 배열 [4]; 4, 3, 2, 1};

(닫는 중괄호와 세미콜론에 유의하십시오)

세 번째 줄 : +`((\w+[).+;(\S+ )*)(-?\d+).+

이것은 루프 섹션입니다. 이는 루프의 어떤 단계도 입력을 변경하지 않을 때까지 실행됨을 의미합니다. 먼저 배열 이름을 찾은 다음 여는 괄호를 찾습니다 : (\w+\[). 그런 다음 임의의 수의 문자와 세미콜론 : .+;. 그런 다음 목록과 다시 일치하지만 이번에는 각 숫자 다음에 숫자와 쉼표 만 표시되며 그 뒤에 공백이 있습니다 (\S+ )*. 그런 다음 목록의 마지막 숫자 (-?\d+)와 그 뒤에 남은 모든 문자를 캡처합니다 .+.

넷째 줄 : $1¶$2$#3] = $4;

그런 다음 배열 이름과 목록으로 바꾸고 줄 바꿈을 $1¶합니다. 다음으로, 마지막 요소 (본질적으로 list.length - 1) 없이 배열 이름 뒤에 이전에 일치 한 목록의 길이를 넣습니다 $2$#3. 뒤에 공백이있는 닫는 대괄호와 어설 션 연산자가 이어지고, 그 다음에 숫자 목록의 마지막 요소가옵니다.] = $4;

처음 교체 한 후 내부 표현은 다음과 같습니다.

short array[4];4, 3, 2,
array[3] = 1;

닫는 중괄호와 세미콜론 .+은 세 번째 줄의 끝으로 인해 사라졌습니다 . 세 번 더 교체 한 후 내부 표현은 다음과 같습니다.

short array[4];
array[0] = 4;
array[1] = 3;
array[2] = 2;
array[3] = 1;

세 번째 줄과 일치하는 항목이 없기 때문에 네 번째 줄은 아무것도 바꾸지 않으며 문자열이 반환됩니다.

TL; DR : 먼저 int list 형식을 약간 변경합니다. 그런 다음 목록의 마지막 요소와 이름을 가져 와서 배열 초기화 후에 넣습니다. 우리는 int리스트가 비워 질 때까지 이것을한다. 그런 다음 변경된 코드를 다시 제공합니다.

온라인으로 사용해보십시오!


답변

V, 37 바이트

2Eé0òYp6ldf ò$dT]ddÎdwf{xwC;
gg"1P

V는 필자가 작성한 2D 문자열 기반 골프 언어로 vim으로 설계되었습니다. 이것은 커밋 17에서 작동합니다 .

설명:

이것은 상당히 짧지 만 내 vim 답변 의 직접적인 번역입니다 .

2E                               "Move to the end of 2 words forward.
  é0                             "Insert a single '0'
    ò       ò                    "Recursively do:
     Yp6ldf                      "Yank, paste, move 6 right, delete until space.
             $dT]                "Move to the end of line, delete backwards until ']'
                 dd              "Delete this line
                   Î             "Apply the following to every line:
                    dwf{xwC;<\n> "Delete word, move to '{' and delete it, Change to end of line, and enter ';'

그런 다음 우리는 단지

gg"1P     "Move to line 1, and paste buffer '1' behind us.

이 유니 코드 광기를 입력하기 어려울 수 있으므로이 뒤집을 수있는 16 진 덤프로 파일을 만들 수 있습니다.

00000000: 3245 e930 f259 7001 366c 6466 20f2 2464  2E.0.Yp.6ldf .$d
00000010: 545d 6464 ce64 7766 7b78 7743 3b0d 6767  T]dd.dwf{xwC;.gg
00000020: 2231 500a                                "1P.

V를 설치하고 다음을 입력하여 실행할 수 있습니다.

python main.py c_array.v --f=file_with_original_text.txt

답변

C, 215 바이트 , 196 바이트

@tucuxi 덕분에 19 바이트가 절약되었습니다!

골프 :

char i[99],o[999],b[99],z[99];t,x,n,c;main(){gets(i);sscanf(i,"%s %[^[]s",b,z);while(sscanf(i+t,"%*[^0-9]%d%n",&x,&n)==1)sprintf(o,"%s[%d] = %d;\n",z,c++,x),t+=n;printf("%s %s[%d];\n%s",b,z,c,o);}

언 골프 드 :

/*
 *  Global strings:
 *   i: input string
 *   o: output string
 *   b: input array type
 *   z: input array name
*/
char i[ 99 ], o[ 999 ], b[ 99 ], z[ 99 ];

/* Global ints initialized to zeros */
t, x, n, c;

main()
{
    /* Grab input string from stdin, store into i */
    gets( i );

    /* Grab the <type> <array_name> and store into b and z */
    sscanf( i, "%s %[^[]s", b, z );

    /* Grab only the int values and concatenate to output string */
    while( sscanf( i + t, "%*[^0-9]%d%n", &x, &n ) == 1 )
    {
        /* Format the string and store into a */
        sprintf( o, "%s[%d] = %d;\n", z, c++, x );

        /* Get the current location of the pointer */
        t += n;
    }

    /* Print the <type> <array_name>[<size>]; and output string */
    printf( "%s %s[%d];\n%s", b, z, c, o );
}

링크:

http://ideone.com/h81XbI

설명:

를 얻으려면 <type> <array_name>sscanf()형식 문자열이 있습니다 :

%s          A string delimited by a space
    %[^[]   The character set that contains anything but a `[` symbol
         s  A string of that character set

string에서 int 값을 추출하려면 int foo[] = {4, 8, 15, 16, 23, 42};본질적 으로이 함수를 사용하여 문자열을 토큰 화하십시오.

while( sscanf( i + t, "%*[^0-9]%d%n", &x, &n ) == 1 )

어디:

  • i입력 문자열입니다 (a char*)
  • t 포인터 위치 오프셋 i
  • xint문자열에서 실제 파싱됩니다.
  • n 찾은 숫자를 포함하여 소비 된 총 문자입니다.

sscanf()형식 문자열이 의미 :

%*            Ignore the following, which is..
  [^0-9]      ..anything that isn't a digit
        %d    Read and store the digit found
          %n  Store the number of characters consumed

입력 문자열을 char 배열로 시각화하는 경우 :

int foo[] = {4, 8, 15, 16, 23, 42};
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
00000000001111111111222222222233333
01234567890123456789012345678901234

가와 int 4, 인덱스 (13)에 위치되는 8등 지수 16이 무엇 같은 루프 모양의 각 실행의 결과입니다 :

Run 1)  String: "int foo[] = {4, 8, 15, 16, 23, 42};"
        Starting string pointer: str[ 0 ]
        Num chars consumed until after found digit: 14
        Digit that was found: 4
        Ending string pointer: str[ 14 ]

Run 2)  String: ", 8, 15, 16, 23, 42};"
        Starting string pointer: str[ 14 ]
        Num chars consumed until after found digit: 3
        Digit that was found: 8
        Ending string pointer: str[ 17 ]

Run 3)  String: ", 15, 16, 23, 42};"
        Starting string pointer: str[ 17 ]
        Num chars consumed until after found digit: 4
        Digit that was found: 15
        Ending string pointer: str[ 21 ]

Run 4)  String: ", 16, 23, 42};"
        Starting string pointer: str[ 21 ]
        Num chars consumed until after found digit: 4
        Digit that was found: 16
        Ending string pointer: str[ 25 ]

Run 5)  String: ", 23, 42};"
        Starting string pointer: str[ 25 ]
        Num chars consumed until after found digit: 4
        Digit that was found: 23
        Ending string pointer: str[ 29 ]

Run 6)  String: ", 42};"
        Starting string pointer: str[ 29 ]
        Num chars consumed until after found digit: 4
        Digit that was found: 42
        Ending string pointer: str[ 33 ]

답변

C, 195180 바이트

195 바이트 원본 :

골프 :

char*a,*b,*c,*d;j;main(i){scanf("%ms %m[^]]%m[^;]",&a,&b,&c);
for(d=c;*d++;i+=*d==44);printf("%s %s%d];\n",a,b,i);
for(d=strtok(c,"] =,{}");j<i;j++,d=strtok(0," ,}"))printf("%s%d] = %s;\n",b,j,d);}

언 골프 :

char*a,*b,*c,*d;
j;
main(i){
    scanf("%ms %m[^]]%m[^;]",&a,&b,&c); // m-modifier does its own mallocs
    for(d=c;*d++;i+=*d==44);            // count commas
    printf("%s %s%d];\n",a,b,i);        // first line
    for(d=strtok(c,"] =,{}");j<i;j++,d=strtok(0," ,}"))
        printf("%s%d] = %s;\n",b,j,d);  // each array value
}

두 개의 단축키는 m수정자를 사용하여 scanf가 %s자체 메모리를 할당하고 (문자 배열을 선언하는 저장), strtok숫자 구문 분석 부분을 수행하기 위해 (기본적으로 포함 가능)을 사용합니다.


180 바이트 업데이트 :

char*a,*b,*c,e[999];i;main(){scanf("%ms %m[^]]%m[^}]",&a,&b,&c);
for(c=strtok(c,"] =,{}");sprintf(e,"%s%s%d] = %s;\n",e,b,i++,c),
c=strtok(0," ,"););printf("%s %s%d];\n%s",a,b,i,e);}

언 골프 :

char*a,*b,*c,e[999];
i;
main(){
    scanf("%ms %m[^]]%m[^}]",&a,&b,&c);
    for(c=strtok(c,"] =,{}");sprintf(e,"%s%s%d] = %s;\n",e,b,i++,c),c=strtok(0," ,"););
    printf("%s %s%d];\n%s",a,b,i,e);
}

쉼표를 계산하지 않도록 문자열에 추가하는 bnf679의 아이디어를 사용 합니다.


답변

Python 3.6 (시험판), 133

m,p=str.split,print;y,u=m(input(),'[');t,n=m(y);i=m(u[5:-2],', ')
l=len(i);p(t,n+f'[{l}];')
for x in range(l):p(n+f'[{x}] = {i[x]};')

f- 문자열을 많이 사용 합니다.

언 골프 버전 :

y, u = input().split('[')
t, n = y.split()
i = u[5:-2].split(', ')
l = len(i)
print(t, n + f'[{l}];')
for x in range(l):
    print(n + f'[{x}] = {i[x]};')