Mở rộng mảng C


36

Trong ngôn ngữ lập trình C, các mảng được định nghĩa như sau:

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

Kích thước của mảng được suy ra từ các phần tử khởi tạo, trong trường hợp này là 6. Bạn cũng có thể viết một mảng C theo cách này, định cỡ rõ ràng sau đó xác định từng phần tử theo thứ tự:

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;

Các thách thức

Bạn phải viết một chương trình hoặc hàm mở rộng mảng từ cách thứ nhất sang cách thứ hai. Vì bạn đang viết một chương trình để làm cho mã dài hơn và bạn thích sự mỉa mai, bạn phải làm cho mã của mình càng ngắn càng tốt.

Đầu vào sẽ là một chuỗi đại diện cho mảng ban đầu và đầu ra sẽ là định nghĩa mảng mở rộng. Bạn có thể giả định một cách an toàn rằng đầu vào sẽ luôn trông như thế này:

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

"Loại" và "mảng_name" sẽ tạo thành hoàn toàn các ký tự bảng chữ cái và dấu gạch dưới _. Các yếu tố của danh sách sẽ luôn là một số trong phạm vi -2,147,483,648 đến 2,147,483,647. Đầu vào ở bất kỳ định dạng nào khác không cần phải xử lý.

Khoảng trắng trong đầu ra của bạn phải khớp chính xác với khoảng trắng trong đầu ra thử nghiệm, mặc dù một dòng mới được cho phép.

Kiểm tra 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;

Đệ trình bằng bất kỳ ngôn ngữ nào đều được khuyến khích, nhưng điểm thưởng nếu bạn có thể thực hiện bằng C.

Bảng xếp hạng:

Dưới đây là bảng xếp hạng hiển thị các câu trả lời hàng đầu:


2
Là khoảng trắng giữa chỉ số mảng, dấu bằng và các giá trị được yêu cầu trong đầu ra? Ví dụ, sẽ foo[0]=1;được chấp nhận?
Mego

@Mego Điều đó sẽ không được chấp nhận. Khoảng trắng là bắt buộc. Tôi sẽ chỉnh sửa nó trong.
DJMcMayhem

Trailing newline được phép?
Luis Mendo

Các chức năng có được phép không?
Mego

Có thể trả lại đầu ra thay vì in nó? (trong trường hợp chức năng)
vaultah

Câu trả lời:


12

Bình thường, 44 byte

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

Bộ kiểm tra

Biểu thức chính quy và cắt chuỗi. Không đặc biệt thông minh.

Giải trình:

++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.

Câu trả lời này là cái gai ở phía tôi. Tôi nghĩ rằng tôi sẽ có thể giành được nó trong vim, nhưng đối với cuộc sống của tôi, tôi không thể nhận được 2-3 byte cuối cùng. = D Câu trả lời hay!
DJMcMayhem

28

Vim, 54, 52, 49 47 tổ hợp phím


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

Giải trình:

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

Bây giờ bộ đệm của chúng tôi trông như thế này:

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};

và con trỏ của chúng tôi ở dòng cuối cùng.

Một nửa thứ hai:

$                           '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 ';'

Bây giờ mọi thứ có vẻ tốt, chúng ta chỉ cần thêm khai báo mảng ban đầu. Vì vậy chúng tôi làm:

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];"

3
Bất cứ khi nào tôi đọc vim-golf, tôi nhận ra tất cả các mã hóa tôi làm (chủ yếu là các lệnh bàn phím trong trình chỉnh sửa GUI linh tinh của tôi) trông giống như thế này, và tâm trí tôi bị bẻ cong trong một phút (Vim chỉ hoàn thành (và mát hơn)) : P
mèo

Tôi không thể làm việc này - khi tôi nhập "@q" đầu tiên (của "@ qq @ q"), macro sẽ chạy sau đó và dường như chạy xa hơn bình thường, nhận được những thứ như int foo[6] = {và kết thúc bằng int foo[12(con trỏ trên "2")
LordAro

@LordAro Có lẽ tôi nên đề cập đến điều đó. Đó là bởi vì đã có một macro trong q và nó chạy trong khi bạn ghi âm, làm hỏng nó. Tôi đã giải thích làm thế nào để giải quyết vấn đề này tại đây: codegolf.stackexchange.com/a/74663/31716
DJMcMayhem

1
@LordAro Oh, duh, tôi biết những gì gây ra điều đó. Tôi đã thay đổi df<space>để dWlưu một byte, nhưng tôi quên rằng nó df<space>sẽ thoát ra khỏi macro trên dòng 6, nhưng dWkhông được. Tôi sẽ khôi phục bản sửa đổi. Cảm ơn đã chỉ ra rằng!
DJMcMayhem

1
Mặc dù đây không phải là câu trả lời ngắn nhất, nhưng cho đến nay nó là ấn tượng nhất.
isaacg

10

Võng mạc, 108 104 100 69 byte

Số lượng byte giả định mã hóa ISO 8859-1.

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

Đánh bại nó, PowerShell ...

Giải thích mã

Dòng đầu tiên: ].+{((\S+ ?)+)

Trước tiên, chúng ta cần giữ kiểu, tên mảng và dấu ngoặc mở (nó tiết kiệm một byte), vì vậy chúng ta không khớp chúng. Vì vậy, chúng tôi khớp với khung đóng, bất kỳ số lượng ký tự và dấu ngoặc nhọn mở : ].+{. Sau đó, chúng tôi phù hợp với danh sách số. Ngắn nhất tôi có thể tìm thấy cho đến nay là đây : ((\S+ ?)+). Chúng tôi khớp bất kỳ số lượng ký tự không phải khoảng trắng nào (bao gồm số, dấu âm có thể có và dấu phẩy có thể), theo sau là khoảng trắng, có thể có hoặc không có ở đó : \S+ ?. Nhóm nhân vật này sau đó được lặp lại nhiều lần nếu cần: (\S+ ?)+và đưa vào nhóm bắt giữ lớn. Lưu ý rằng chúng tôi không khớp với dấu ngoặc nhọn hoặc dấu chấm phẩy. Giải thích dòng thứ ba cho biết tại sao.

Dòng thứ hai: $#2];$1

Vì chúng tôi chỉ khớp một phần của đầu vào, nên các phần chưa từng có sẽ vẫn ở đó. Vì vậy, chúng tôi đặt chiều dài của danh sách sau khung mở chưa từng có : $#2. Công cụ sửa đổi thay thế #giúp chúng tôi làm điều đó, vì nó cho chúng tôi số lượng trận đấu mà một nhóm bắt giữ cụ thể đã thực hiện. Trong trường hợp này bắt nhóm 2. Sau đó, chúng tôi đặt một dấu ngoặc đóng và dấu chấm phẩy, và cuối cùng là toàn bộ danh sách của chúng tôi.

Với đầu vào short array[] = {4, 3, 2, 1};, đại diện bên trong sau khi thay thế này là:

mảng ngắn [4]; 4, 3, 2, 1};

(lưu ý dấu ngoặc nhọn và dấu chấm phẩy)

Dòng thứ ba: +`((\w+[).+;(\S+ )*)(-?\d+).+

Đây là một phần lặp. Điều đó có nghĩa là nó chạy cho đến khi không có giai đoạn nào trong vòng lặp thực hiện thay đổi đầu vào. Đầu tiên chúng ta khớp tên mảng, theo sau là dấu ngoặc mở : (\w+\[). Sau đó, một số tùy ý của bất kỳ ký tự và dấu chấm phẩy : .+;. Sau đó, chúng tôi khớp danh sách một lần nữa, nhưng lần này chỉ có các số và dấu phẩy sau mỗi số, có một khoảng trắng theo sau chúng : (\S+ )*. Sau đó, chúng tôi nắm bắt số cuối cùng trong danh sách: (-?\d+)và bất kỳ ký tự nào còn lại đằng sau nó : .+.

Dòng thứ tư: $1¶$2$#3] = $4;

Sau đó, chúng tôi thay thế nó bằng tên mảng và danh sách theo sau là một dòng mới : $1¶. Tiếp theo, chúng tôi đặt tên mảng, theo sau là độ dài của danh sách phù hợp trước đó, không có phần tử cuối cùng (về cơ bản list.length - 1) : $2$#3. Tiếp theo là một khung đóng và toán tử xác nhận có khoảng trắng và tiếp theo là phần tử cuối cùng của danh sách số của chúng tôi:] = $4;

Sau lần đầu tiên thay thế, đại diện bên trong trông như thế này:

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

Lưu ý rằng dấu ngoặc nhọn đóng và dấu chấm phẩy biến mất, nhờ .+vào cuối dòng thứ ba. Sau ba lần thay thế, đại diện bên trong trông như thế này:

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

Vì không còn gì phù hợp với dòng thứ ba, thứ tư không thay thế bất cứ thứ gì và chuỗi được trả về.

TL; DR: Đầu tiên chúng tôi thay đổi định dạng danh sách int một chút. Sau đó, chúng tôi lấy phần tử cuối cùng của danh sách và tên, và đặt chúng sau khi khởi tạo mảng. Chúng tôi làm điều này cho đến khi danh sách int trống. Sau đó, chúng tôi cung cấp mã thay đổi trở lại.

Hãy thử trực tuyến!


Ai đó đã đánh bại tôi với nó .... :(
CalculatorFeline

M!`G`tương tự nhau, nhưng không hoàn toàn giống nhau. Hãy cẩn thận.
Máy

Giải thích dòng thứ ba làm tôi bối rối. Mục đầu tiên là mục duy nhất không có khoảng trắng phía sau, không phải mục cuối cùng.
Máy

@CatsAreFluffy Tôi đã cố gắng thay đổi từ ngữ một chút ngay bây giờ. Ý tôi là một không gian theo sau một con số, không có trước nó. Tôi đoán tôi đã không nhận ra đầy đủ ý nghĩa của "phía sau". Tôi thực sự không nên viết giải thích mã lúc 2 giờ sáng.
daavko

@daavko "Phía sau" thường có nghĩa là "sau" tức là "theo sau", trong tiếng Anh thông tục. Bạn vẫn ổn
Nic Hartley

9

V, 37 byte

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

V là một ngôn ngữ chơi gôn dựa trên chuỗi 2D mà tôi đã viết, được thiết kế từ vim. Điều này hoạt động như cam kết 17 .

Giải trình:

Đây là bản dịch trực tiếp câu trả lời vim của tôi , mặc dù ngắn hơn đáng kể.

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 ';'

Sau đó, chúng tôi chỉ có:

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

Vì sự điên rồ unicode này có thể khó nhập, bạn có thể tạo tệp với hexdump có thể đảo ngược này:

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.

Điều này có thể được chạy bằng cách cài đặt V và gõ:

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

1
Designed off of vim.2 lưu ý: 1. hầu hết mọi người nói fromkhông off of, và 2. tại sao điều này không tồn tại. +1
Rɪᴋᴇʀ

8

C, 215 byte , 196 byte

19 byte được lưu nhờ vào @tucuxi!

Chơi gôn

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);}

Ung dung:

/*
 *  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 );
}

Liên kết:

http://ideone.com/h81XbI

Giải trình:

Để có được <type> <array_name>, sscanf()chuỗi định dạng là:

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

Để trích xuất các giá trị int từ chuỗi int foo[] = {4, 8, 15, 16, 23, 42};, về cơ bản, tôi mã hóa chuỗi bằng hàm này:

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

Ở đâu:

  • ilà chuỗi đầu vào (a char*)
  • t là vị trí con trỏ bù của i
  • xintphân tích cú pháp thực tế từ chuỗi
  • n là tổng số ký tự được tiêu thụ, bao gồm cả chữ số tìm thấy

Chuỗi sscanf()định dạng có nghĩa là:

%*            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

Nếu bạn hình dung chuỗi đầu vào dưới dạng mảng char:

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

với int 4vị trí nằm ở chỉ số 13, 8tại chỉ số 16, v.v., đây là kết quả của mỗi lần chạy trong vòng lặp trông như sau:

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 ]

1
bạn có thể tránh sử dụng strcat bằng cách ghép nối obên trong sprintf, thông qua %s. Điều này sẽ cạo khoảng 7 ký tự.
tucuxi

@tucuxi Ah, bắt tốt. Cảm ơn!
homersimpson

7

C, 195 180 byte

Bản gốc 195 byte:

đánh gôn

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);}

vô dụng:

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
}

Hai phím tắt đang sử dụng công cụ msửa đổi để có được bộ quét %sđể phân bổ bộ nhớ riêng (lưu khai báo mảng char) và sử dụng strtok(cũng có sẵn theo mặc định, không bao gồm) để thực hiện phần phân tích số.


Cập nhật 180 byte:

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);}

vô dụng:

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);
}

Sử dụng bnf679 ý tưởng về việc gắn vào chuỗi để tránh phải tính dấu phẩy.


6

Python 3.6 (tiền phát hành), 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]};')

Làm cho sử dụng nặng chuỗi f .

Phiên bản bị đánh cắp:

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]};')

1
Woah, tôi quên mất chuỗi f. Đó sẽ là siêu hữu ích cho golf!
Morgan Thrapp

Tôi nghĩ rằng bạn có thể lưu một byte bằng cách sử dụng một sự hiểu biết danh sách thay vì vòng lặp thông thường
someonewithpc

@someonewithpc: không, nó thực sự sẽ thêm 1 byte
vaultah

5

Hồng ngọc, 127 110 108 99 88 byte

Hàm ẩn danh với một đối số là đầu vào. Chương trình đầy đủ, đọc đầu vào từ STDIN. (Nếu bạn đặt một tệp vào, dòng mới theo dõi là tùy chọn.) Trả về In chuỗi đầu ra.

Lấy @TimmyD khoe khoang về giải pháp của họ đánh bại tất cả những người không phải là esolang khác như một thách thức, và cuối cùng đã vượt qua (tại thời điểm viết) giải pháp Powershell 114 byte mà họ đã đăng. Thủ thuật của O'Bᴏɴᴏʀ với việc chia tách] và ghép nửa sau để có được các số trợ giúp.

Tôi cần sử dụng toán tử splat nhiều hơn. Nó rất hữu ích!

Mượn một mẹo từ câu trả lời JavaScript ES6 của @ Neil để tiết kiệm nhiều byte hơn bằng cách quét các từ thay vì sử dụng gsubsplit..

t,n,*l=gets.scan /-?\w+/;i=-1
puts t+" #{n}[#{l.size}];",l.map{|e|n+"[#{i+=1}] = #{e};"}

AFAICT nhiệm vụ là viết một chương trình đầy đủ.
vaultah

@vaultah Mặc định cho mã golf là một chương trình hoặc chức năng
Mego

@Mego: OP nói "Bạn phải viết chương trình"
vaultah

@vaultah bình thường tôi sẽ nói rằng mã golf cho phép tôi sử dụng một hàm, nhưng một chương trình đầy đủ đã tiết kiệm cho tôi 2 byte, vậy tại sao không?
Mực giá trị

Ôi ... Tôi không nghĩ PowerShell có thể làm được điều đó. Có +1
admBorkBork

4

05AB1E , 52 50 47 byte

Mã số:

… = ¡`¦¨¨ð-',¡©gr¨s«„];«,®v¹ð¡¦¬s\¨N"] = "y';J,

Sử dụng mã hóa CP-1252 . Hãy thử trực tuyến! .


1
Đã đến lúc tôi bỏ qua tất cả các câu trả lời khác chỉ tìm kiếm câu trả lời 05AB1E của bạn. Ngôn ngữ hoàn toàn cuốn hút tôi.
WorseDoughnut

1
@WorseDoughnut Cảm ơn bạn! Đó là điều tốt đẹp nhất mà ai đó đã từng nói với tôi về 05AB1E :)!
Ad Nam

4

JavaScript (ES6), 100 byte

(s,[t,n,...m]=s.match(/-?\w+/g))=>t+` ${n}[${m.length}];`+m.map((v,i)=>`
${n}[${i}] = ${v};`).join``

Vì chỉ các từ là quan trọng, điều này hoạt động bằng cách chỉ khớp tất cả các từ trong chuỗi gốc, cộng với các dấu trừ hàng đầu, sau đó xây dựng kết quả. (Ban đầu tôi nghĩ mình sẽ sử dụng replacenhưng hóa ra đó là cá trích đỏ.)


[t,n,...m]gần như một viễn cảnh huyền bí
edc65


4

Pip , 48 47 byte

qR`(\S+)(. = ).(.+)}`{[b#Yd^k']';.n.b.,#y.c.y]}

Đưa đầu vào từ stdin và in ra thiết bị xuất chuẩn.

Giải trình

Tl; dr: Có thay thế regex không, sử dụng các nhóm bắt giữ và chức năng gọi lại để xây dựng kết quả.

Biến qđặc biệt đọc một dòng đầu vào. Regex là (\S+)(. = ).(.+)}, phù hợp với tất cả mọi thứ trừ loại (bao gồm cả dấu cách) và dấu chấm phẩy cuối cùng. Sử dụng ví dụ đầu tiên từ các câu hỏi, các nhóm chụp được foo[, ] = 4, 8, 15, 16, 23, 42.

Thay thế là giá trị trả về của hàm không tên {[b#Yd^k']';.n.b.,#y.c.y]}, được gọi với toàn bộ khớp cộng với các nhóm bắt giữ làm đối số. Do đó, trong hàm, blấy nhóm 1, clấy nhóm 2 và dlấy nhóm 3.

Chúng tôi xây dựng một danh sách, ba mục đầu tiên trong số đó sẽ là "foo[", 6"]". Để có được 6, chúng tôi chia dtrên biến tích hợp k= ", ", Yxem danh sách các số nguyên kết quả thành ybiến để sử dụng trong tương lai và lấy độ dài ( #).']là một nhân vật theo nghĩa đen.

Những gì còn lại là để xây dựng một chuỗi các chuỗi của biểu mẫu ";\nfoo[i] = x". Để làm như vậy, chúng tôi ghép các phần sau : ';, n(tích hợp sẵn cho dòng mới), b(nhóm chụp thứ nhất), ,#y(tương đương với Python range(len(y))), c(nhóm chụp thứ 2) và y. Sự kết hợp hoạt động theo từng mục trên danh sách và phạm vi, do đó, kết quả là một danh sách các chuỗi. Đặt tất cả lại với nhau, giá trị trả về của hàm sẽ là một danh sách như sau:

["foo[" 6 "]"
 [";" n "foo[" 0 "] = " 4]
 [";" n "foo[" 1 "] = " 8]
 [";" n "foo[" 2 "] = " 15]
 [";" n "foo[" 3 "] = " 16]
 [";" n "foo[" 4 "] = " 23]
 [";" n "foo[" 5 "] = " 42]
]

Vì danh sách này đang được sử dụng trong một vị trí chuỗi R, nên nó được truyền ngầm thành một chuỗi. Chuyển đổi danh sách thành chuỗi mặc định trong Pip đang nối tất cả các thành phần:

"foo[6];
foo[0] = 4;
foo[1] = 5;
foo[2] = 15;
foo[3] = 16;
foo[4] = 23;
foo[5] = 42"

Cuối cùng, kết quả (bao gồm loại và dấu chấm phẩy cuối cùng, không khớp với biểu thức chính quy và do đó không thay đổi) được in tự động.


4

Perl 5.10, 73 72 68 66 + 1 (chuyển đổi -n) = 67 byte

perl -nE '($t,$n,@a)=/[-[\w]+/g;say"$t $n".@a."];";say$n,$i++,"] = $_;"for@a'

Đây là một thách thức tốt cho Perl và ngắn nhất trong số các ngôn ngữ có mục đích chung cho đến nay. Tương đương với

($t, $n, @a) = /[-[\w]+/g;
say "$t $n" . @a . "];";
say $n, $i++, "] = $_;" for @a;

4

PowerShell v2 +, 114 105 byte

$a,$b,$c,$d=-split$args-replace'\[]';"$a $b[$(($d=-join$d|iex|iex).length)];";$d|%{"$b[$(($i++))] = $_;"}

Lấy chuỗi đầu vào $args-replaces khung vuông không có gì, sau đó thực hiện một -splitkhoảng trắng. Chúng tôi lưu trữ bit đầu tiên vào $a, bit thứ hai vào $b, =vào $cvà các phần tử mảng vào $d. Đối với ví dụ dưới đây, cửa hàng này foovào $abarvào $b, và tất cả các mảng vào $d.

Chúng tôi sau đó sản lượng dòng đầu tiên của chúng tôi với "$a ..."và ở giữa chuyển đổi $dtừ một một mảng của chuỗi các hình thức {1,, 2,... 100};đến một int mảng thường xuyên bởi -joining nó lại với nhau thành một chuỗi, sau đó chạy nó thông qua iexhai lần (tương tự eval). Chúng tôi lưu trữ mảng kết quả đó trở lại $dtrước khi gọi .lengthphương thức để điền số thích hợp vào giữa[] dòng đầu ra.

Chúng tôi sau đó gửi $dqua một vòng lặp với |%{...}. Mỗi lần lặp chúng ta xuất ra "$b..."với một biến đếm được $igói gọn trong ngoặc và giá trị hiện tại $_. Các $ibiến bắt đầu uninitialized (tương đương $null) nhưng ++sẽ bỏ nó vào một inttrước khi đầu ra, do đó nó sẽ bắt đầu sản xuất tại 0, tất cả trước khi incrementing $icho vòng lặp kế tiếp.

Tất cả các dòng đầu ra được để lại trên đường ống và đầu ra cho thiết bị đầu cuối được ẩn khi kết thúc chương trình.

Thí dụ

PS C:\Tools\Scripts\golfing> .\expand-a-c-array.ps1 "foo bar[] = {1, 2, 3, -99, 100};"
foo bar[5];
bar[0] = 1;
bar[1] = 2;
bar[2] = 3;
bar[3] = -99;
bar[4] = 100;

Phù! Tôi đã xoay sở để đưa câu trả lời Ruby của mình vượt qua bạn bằng cách nhận xét của bạn về việc đánh bại những người không phải là esolang khác như một thách thức! Công việc tốt, mặc dù, +1.
Mực giá trị

@KevinLau Cảm ơn! Trở lại ya với 105 bây giờ. ;-)
admBorkBork

Tôi sẽ gọi 105 của bạn và nâng bạn 99! : D
Mực giá trị

Không còn đóng cửa trong việc đánh bại Retina.
Máy

3

C, 278 280 byte

đánh gôn

x,e,l,d;char *m,*r,*a;char i[999];c(x){return isdigit(x)||x==45;}main(){gets(i);m=r=&i;while(*r++!=32);a=r;while(*++r!=93);l=r-a;d=r-m;for(;*r++;*r==44?e++:1);printf("%.*s%d];\n",d,m,e+1);r=&i;while(*r++){if(c(*r)){m=r;while(c(*++r));printf("%.*s%d] = %.*s;\n",l,a,x++,r-m,m);}}}

vô dụng:

/* global ints
 * x = generic counter
 * e = number of elements
 * l = length of the array type
 * d = array defination upto the first '['
 */
x,e,l,d;
/* global pointers
 * m = memory pointer
 * r = memory reference / index
 * a = pointer to the start of the array type string
 */
char *m,*r,*a;
/* data storage for stdin */
char i[999];
c(x){return isdigit(x)||x=='-';}
main(){
    gets(i);
    m=r=&i;
    while(*r++!=32);                // skip first space
    a=r;
    while(*++r!=93);                // skip to ']'
    l=r-a;
    d=r-m;
    for(;*r++;*r==44?e++:1);        // count elements
    printf("%.*s%d];\n",d,m,e+1);   // print array define
    r=&i;
    while(*r++) {                   // print elements
        if(c(*r)) {                 // is char a - or a digit?
            m=r;
            while(c(*++r));         // count -/digit chars
            printf("%.*s%d] = %.*s;\n",l,a,x++,r-m,m);
        }
    }
}

Trong khi làm việc trên một số người này đã đăng một phiên bản ngắn hơn bằng cách sử dụng sscanf để phân tích cú pháp thay vì sử dụng con trỏ dữ liệu ... một cái hay!

CẬP NHẬT: Phát hiện các khoảng trống bị thiếu xung quanh bằng với phần tử in, liên kết trực tuyến IDE: http://ideone.com/KrgRt0 . Lưu ý việc triển khai này không hỗ trợ số âm ...


2

Awk, 101 byte

{FS="[^[:alnum:]_-]+";printf"%s %s[%d];\n",$1,$2,NF-3;for(i=3;i<NF;i++)printf$2"[%d] = %d;\n",i-3,$i}

Dễ đọc hơn:

{
FS="[^[:alnum:]_-]+"
printf "%s %s[%d];\n", $1, $2, NF - 3
for (i=3; i < NF; i++)
    printf $2"[%d] = %d;\n", i-3, $i
}
  • Tôi đặt dấu phân cách trường thành mọi thứ trừ bảng chữ cái, chữ số, dấu gạch dưới và -. Vì vậy, các trường sẽ là tên loại, tên biến và số.
  • Số lượng các trường sẽ là 1 (cho loại) + 1 (cho tên) + N (số) + 1 (một trường trống sau khi theo dõi }; ). Vì vậy, kích thước của mảng làNF - 3 .
  • Sau đó, nó chỉ in một dòng đặc biệt để khai báo và lặp qua các con số.
  • Tôi nên gán FShoặc khi gọi awk (sử dụng -F) hoặc trong một BEGINkhối. Vì lợi ích của sự ngắn gọn, nên.

1
Trên thực tế, FSphải được chỉ định BEGINhoặc sử dụng -Fnếu không nó sẽ không được sử dụng để phân chia dòng đầu tiên và vì chỉ có 1 dòng đầu vào ...
Robert Benson

@RobertBenson bạn nói đúng, nên lệnh sẽ awk '-F[^[:alnum:]_-]+' '{printf"%s %s[%d];\n",$1,$2,NF-3;for(i=3;i<NF;i++)printf$2"[%d] = %d;\n",i-3,$i}'là 102 byte không tính awkchính nó. Hừm. Tôi có thể loại trừ các trích dẫn?
muru

Có, bạn có thể loại trừ dấu ngoặc kép. Đôi khi bạn liệt kê nó như là C+O bytesnơi COđại diện cho các byte từ mã và các tùy chọn tương ứng. Tất nhiên tôi thường chỉ sử dụng một BEGINkhối, vì vậy tôi không phải suy nghĩ về nó. : p
Robert Benson

2

JavaScript ES6, 134 132 130 129 byte

Đã lưu 1 byte nhờ Neil.

x=>(m=x.match(/(\w+) (\w+).+{(.+)}/),m[1]+` `+(q=m[2])+`[${q.length-1}];
`+m[3].split`, `.map((t,i)=>q+`[${i}] = ${t};`).join`
`)

Không nên `[${i}] = `+t+";"`[${i}] = ${t};`?
Neil

@Neil Cảm ơn, đã lưu một byte!
Conor O'Brien

2

bash, 133 129 byte

read -a l
d="${l[@]:0:2}"
e=("${l[@]:3}")
echo "${d%?}${#e[@]}];"
for i in "${!e[@]}"
{
echo "${l[0]}[$i] = ${e[$i]//[!0-9]/};"
}

Nỗ lực đầu tiên, chắc chắn rằng nó có thể làm cho nó ngắn hơn.


2

D, 197 , 188 byte

import std.array,std.stdio;void main(){string t,n,e;readf("%s %s] = {%s}",&t,&n,&e);auto v=e.replace(",","").split;writeln(t,' ',n,v.length,"];");foreach(i,c;v)writeln(n,i,"] = ",c,";");}

hoặc vô lương tâm:

import std.array, std.stdio;

void main() {
    string type, nameAndBracket, elems;
    readf("%s %s] = {%s}", &type, &nameAndBracket, &elems);

    // remove all commas before splitting the string into substrings
    auto vector = elems.replace(",","").split();

    // writeln is shorter than fln by 1 char when filled in
    writeln(type, ' ', nameAndBracket, vector.length, "];");

    // print each element being assigned
    foreach(index, content; vector)
        writeln(nameAndBraket, index, "] = ", content, ";");
}

Tôi không biết D, nhưng bạn có thể đọc dấu ngoặc vuông mở như một phần của tên không? Điều đó sẽ giúp bạn tiết kiệm phải viết một dấu ngoặc vuông riêng biệt sau này.
DLosc

2

Julia, 154 134 101 byte

f(s,c=matchall(r"-?\w+",s),n=endof(c)-2)=c[]" "c[2]"[$n];
"join([c[2]"[$i] = "c[i+3]";
"for i=0:n-1])

Đây là một hàm chấp nhận một chuỗi và trả về một chuỗi với một dòng mới duy nhất.

Ung dung:

function f(s, c = matchall(r"-?\w+", s), n = endof(c) - 2)
    c[] " " c[2] "[$n];\n" join([c[2] "[$i] = " x[i+3] ";\n" for i = 0:n-1])
end

Chúng tôi xác định clà một mảng khớp của đầu vào trên biểu thức chính quy -?\w+. Nó caputres loại, tên mảng, sau đó mỗi giá trị. Chúng tôi lưu trữ ndưới dạng độ dài c- 2, là số lượng giá trị. Đầu ra được xây dựng dưới dạng chuỗi, tên và chuỗi độ dài được nội suy, kết hợp với mỗi dòng định nghĩa được phân tách bằng dòng mới. Vì lý do gì, c[]cũng giống nhưc[1] .

Đã lưu 32 byte với sự giúp đỡ từ Dennis!


1

Python 2, 159 byte

s=input().split()
t,n,v=s[0],s[1][:-2],''.join(s[3:])
a=v[1:-2].split(',')
print'%s %s[%d];'%(t,n,len(a))
for i in range(len(a)):print'%s[%d] = %s;'%(n,i,a[i])

Dùng thử trực tuyến

Cảm ơn Kevin Lau cho một số gợi ý chơi golf


1

Python 3, 116 byte

t,v,_,*l=input().split();v=v[:-1]+'%s]'
print(t,v%len(l)+';');i=0
for x in l:print(v%i,'= %s;'%x.strip('{,};'));i+=1

Chia đầu vào thành loại, tên và danh sách các số. Sau khi in khai báo mảng, in các phần tử bằng cách liệt kê thủ công qua các số, loại bỏ các dấu câu thừa được gắn vào đầu tiên và cuối cùng.

Một cách tiếp cận khác nhau trong Python 2 xuất hiện tới 122 byte:

a,b=input()[:-2].split('] = {')
l=eval(b+',')
print a+`len(l)`+"];"
for y in enumerate(l):print a.split()[1]+'%s] = %s;'%y

Ý tưởng là evaldanh sách các số dưới dạng một tuple, với dấu phẩy ở cuối để một số duy nhất được nhận dạng là một loại. Danh sách các số được liệt kê cung cấp các bộ dữ liệu cho định dạng chuỗi trong.


1

PHP, 143 byte

Chơi gôn

<?$t=count($n=explode(' ',preg_replace('/[^\s\w]/','',$argv[1])))-3;echo"$n[0] {$n[1]}[$t];";for($i=2;$t>$j=++$i-3;)echo$n[1]."[$j] = $n[$i];";

Ung dung

<?  
$t = count(                                  // Get the number of elements for our array...
    $n = explode(' ',                            // After split the input on whitespace...
    preg_replace('/[^\s\w]/','',$argv[1])))-3;  // After removing all special characters.
echo "$n[0] {$n[1]}[$t];";                     // First line is type, name, and count.
for($i=2;                                        // Loop through array elements
    $t > $j = ++$i-3;)                         // Assign j to be the actual index for our new array
    echo $n[1]."[$j] = $n[$i];";                // Print each line

Đầu vào được thực hiện thông qua đối số dòng lệnh. Mẫu vật:

C:\(filepath)>php Expand.php "int foo[] = {4,8,15,16,23,42};"

Đầu ra:

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

0

MATL , 68 64 58 byte

'\w+'XX2:H#)XKxXIZc'['KnV'];'v!K"I2X)'['X@qV'] = '@g';'6$h

Đây không phải là C, nhưng nó sử dụng sprintfhàm giống như C , đã lãng phí 4 byte.

Hãy thử trực tuyến!

          % Take input implicitly
'\w+'XX   % Find substrings that match regex '\w+'. Gives a cell array
2:H#)     % Split into a subarray with the first two substrings (type and name), and 
          % another with the rest (numbers that form the array)
XKx       % Copy the latter (numbers) into clipboard K. Delete it
XI        % Copy the former (type and name) into clipboard I
Zc        % Join the first two substrings with a space
'['       % Push this string
K         % Paste array of numbers
nV        % Get its length. Convert to string
'];'      % Push this string
v!        % Concatenate all strings up to now. Gives first line of the output
K"        % For each number in the array
  I2X)    %   Get name of array as a string
  '['     %   Push this string
  X@qV    %   Current iteration index, starting at 0, as a string
  '] = '  %   Push this string
  @g      %   Current number of the array, as a string
  ';'     %   Push this string
  5$h     %   Concatenate top 6 strings. This is a line of the output
          % Implicity end for each
          % Implicitly display

0

Clojure, 115 byte

#(let[[t n & v](re-seq #"-?\w+"%)](apply str t" "n\[(count v)"];\n"(map(fn[i v](str n"["i"] = "v";\n"))(range)v))))

Tôi không thể hợp nhất độc đáo awful_array_name[5];awful_array_name[0] = 7;các bộ phận để họ sử dụng lại mã: /

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.