Розгорніть масив С


36

У мові програмування на 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> ... };

"Тип" та "ім'я масиву" повністю складатимуться з символів алфавіту та підкреслення _. Елементами списку завжди буде число в діапазоні від -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.

Табло:

Ось таблиця таблиць із найкращими відповідями:


2
Чи пропуски між індексом масиву, знаком рівності та значеннями, необхідними у висновку? Наприклад, чи було foo[0]=1;б прийнятним?
Mego

@Mego Це було б не прийнятно. Потрібно пробілити. Я відредагую це.
DJMcMayhem

Дозволений останній рядок?
Луїс Мендо

Чи дозволені функції?
Mego

Чи добре повернути вихід, а не надрукувати його? (у випадку функцій)
vaultah

Відповіді:


12

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, але за все життя я не можу зняти останні 2-3 байти. = D Приємна відповідь!
DJMcMayhem

28

Вім, 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];"

3
Щоразу, коли я читаю vim-golf, я усвідомлюю, що все кодування, яке я роблю (в основному команди клавіатури в моїх різних редакторах GUI), виглядає приблизно так, і мій погляд на хвилину згинається (Vim просто завершує (і крутіше)) : P
кіт

Я не можу змусити це працювати - коли я набираю перший "@q" (з "@ qq @ q"), макрос запускається потім і, мабуть, працює далі, ніж слід, отримуючи такі речі, як int foo[6] = {і закінчуючи int foo[12(курсор на the "2")
LordAro

@LordAro Я, мабуть, повинен був це згадати. Це тому, що в q вже є макрос, який працює під час запису, псуючи його. Я пояснив, як тут обійтись
DJMcMayhem

1
@LordAro О, да, я знаю, що це спричиняє. Я змінив, df<space>щоб dWзберегти байт, але забув, що df<space>вийде з макросу в рядку 6, але dWце не так. Я відкажу версію. Дякуємо, що вказали на це!
DJMcMayhem

1
Хоча це не зовсім коротка відповідь, вона, безумовно, є найбільш вражаючою.
isaacg

10

Сітківка, 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. У цьому #нам допомагає модифікатор заміни , оскільки він дає нам кількість збігів, зроблених певною групою захоплення. У цьому випадку група захоплення2 . Потім ми ставимо дужку закриття і крапку з комою, і, нарешті, весь наш список.

З введенням 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. Потім беремо останній елемент списку та ім'я та вкладаємо їх після ініціалізації масиву. Ми робимо це, поки список int не буде порожнім. Потім повертаємо змінений код назад.

Спробуйте в Інтернеті!


Мене хтось побив .... :(
CalculatorFeline

M!`і G`схожі, але не зовсім однакові. Будь обережний.
CalculatorFeline

Пояснення третього рядка мене бентежать. Перший елемент - єдиний без пробілу, не останній.
CalculatorFeline

@CatsAreFluffy Я спробував трохи змінити формулювання. Я мав на увазі пробіл, що слідує за номером, не передуючи йому. Я думаю, я не повністю зрозумів значення "позаду". Я дійсно не повинен писати пояснення коду о 2 ранку.
daavko

@daavko "Ззаду" зазвичай означає "після", тобто "слідуючи", розмовною англійською мовою. Ви були добре.
Фонд позову Моніки

9

V, 37 байт

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

V - це двовимірна, гофрована мова для гольфу, яку я написав, розроблена від 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.

Оскільки в це безумство unicode важко ввести, ви можете створити файл із цим оборотним шестигранним наказом:

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

1
Designed off of vim.2 примітки: 1. більшість людей каже, що fromні off of, і 2. чому цього не існувало. +1
Rɪᴋᴇʀ

8

C, 215 байт , 196 байт

19 байт збережено завдяки @tucuxi!

Гольф:

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

Щоб отримати значення 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
  • x- це фактичний intаналіз з рядка
  • 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 ]

1
Ви можете уникнути використання strcat, об'єднавши oвсередину sprintf, via %s. Це повинно голитися близько 7 символів.
tucuxi

@tucuxi Ах, хороший улов. Спасибі!
homersimpson

7

С, 195 180 байт

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 про додавання до рядка, щоб уникнути необхідності підрахунку коми.


6

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

1
Вау, я забув про f-рядки. Вони будуть дуже корисні для гольфу!
Морган Трапп

Я думаю, ви можете зберегти байт, скориставшись розумінням списку замість звичайного циклу
whowithpc

@someonewithpc: ні, це насправді додасть 1 зайвий байт
ваталія

5

Рубі, 127 110 108 99 88 байт

Анонімна функція з одним аргументом як вхід.Повна програма, читає вхід зі STDIN. (Якщо ви передаєте файл у файл, останній новий рядок необов’язковий.) Повертається Друкує вихідний рядок.

Узяв @TimmyD похвалитися своїм рішенням, побивши всі інші не-езолангси як виклик, і, нарешті, подолати (на момент написання) 114-байтне рішення Powershell, яке вони опублікували. Трюк Cᴏɴᴏʀ O'Bʀɪᴇɴ з роздвоєнням] та сплайсинг другої половини, щоб допомогти цифрам.

Мені потрібно більше використовувати оператор splat. Це так корисно!

Позичив хитрість з відповіді JavaScript Ne6 JavaScript ES6, щоб зберегти більше байтів, сканувавши слова замість використання gsubта split..

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

ЗАСТОСУВАННЯ завдання - написати повну програму.
vaultah

@vaultah Типовим кодом для гольфу є програма або функція
Mego

@Mego: ОП сказало: "Ви повинні написати програму"
vaultah

@vaultah, як правило, я б сказав, що код гольфу дозволяє використовувати функцію, але повна програма врятувала мене 2 байти, так чому б і ні?
Значення чорнила

На жаль ... я не думаю, що PowerShell може звестись до цього. Майте +1
AdmBorkBork

4

05AB1E , 52 50 47 байт

Код:

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

Використовує кодування CP-1252 . Спробуйте в Інтернеті! .


1
Дійшло до того, що я пропускаю всі інші відповіді, просто шукаючи ваші відповіді 05AB1E. Мова абсолютно мене заворожує.
WorseDoughnut

1
@WorseDoughnut Дякую! Це найприємніше, що хтось коли-небудь говорив мені про 05AB1E :)!
Аднан

4

JavaScript (ES6), 100 байт

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

Оскільки важливі лише слова, це працює, просто зіставляючи всі слова в початковому рядку плюс ведучі знаки мінус, потім будуючи результат. (Спочатку я думав, що збираюся використовувати, replaceале це виявилося червоною оселедець.)


[t,n,...m]майже містичне бачення
edc65


4

Піп , 48 47 байт

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

Здійснює введення від stdin та друкує до stdout.

Пояснення

Tl; dr: Чи проводить заміну регулярних виразів, використовуючи групи захоплення та функцію зворотного виклику для побудови результату.

qСпеціальна змінна зчитує рядок введення. Зворотний вираз є тим (\S+)(. = ).(.+)}, що відповідає всім, крім типу (включаючи пробіл) та остаточну крапку з комою. Використовуючи перший приклад з питання, то захоплюючи групи отримують foo[, ] = і4, 8, 15, 16, 23, 42 .

Заміна - це повернене значення неназваної функції {[b#Yd^k']';.n.b.,#y.c.y]}, яке викликається цілим збігом плюс групи захоплення як аргументи. Таким чином, у межах функції bотримує група захоплення 1, cотримує групу 2 таd отримує групу 3.

Побудуємо список, перші три пункти , які будуть "foo[", 6і "]". Для отримання 6, ми розділимо dна вбудовану змінну k= ", ", Yдодаємо отриманий список цілих чисел до yзмінної для подальшого використання та беремо довжину ( #).']є символом буквальним.

Залишилося побудувати ряд рядків форми ";\nfoo[i] = x". Для цього ми зчепити наступне: ';, n(вбудований для перекладу рядка), b(перший захоплення групи), ,#y(еквівалент Python range(len(y))), c(друга група) захоплення, і y. Конкатенація працює окремо за списками та діапазонами, тому результатом є список рядків. Збираючи все це разом, поверненим значенням функції буде такий список, як цей:

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

Оскільки цей список використовується в Rепіляції рядків , він неявно передається в рядок. Перетворення списку в рядок за замовчуванням у Pip об'єднує всі елементи:

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

Нарешті, результат (включаючи тип та кінцеву крапку з комою, які не узгоджувались регулярним виразом і, таким чином, залишалися незмінними), автоматично друкується.


4

Perl 5.10, 73 72 68 66 + 1 (для -n перемикача) = 67 байт

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

Це приємний виклик для Perl і найкоротший з мов загального призначення до цих пір. Дорівнює

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

4

PowerShell v2 +, 114 105 байт

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

Бере вхідний рядок $argsі -replaceзабирає квадратну дужку без нічого, після чого виконує -splitпробіл. Ми зберігаємо перший шматочок в$a , другий біт в $b, в =INTO $cі елементи масиву в $d. Для прикладу нижче, це зберігається fooв $aтаbar в $b, і весь масив в $d.

Потім виводимо перший рядок із "$a ..."та в середньому перетворенні$d з масиву рядків форми {1,, 2,... 100};в звичайний цілочисельний масив по -joinІНГ разом в один рядок, а потім запустити його через iexдва рази ( по аналогії eval). Ми зберігаємо цей результатний масив назад, $dперш ніж викликати .lengthметод для заповнення відповідного числа між []рядком у вихідному рядку.

Потім відправляємо $dчерез цикл с |%{...}. Кожну ітерацію ми виводимо"$b..." за допомогою змінної лічильника, $iінкапсульованої в дужки, та поточного значення $_. $iМінлива починає неініціалізованих (еквівалент $null) , але ++буде відкидати його на intперед виходом, тому він почне вихід на 0, все перед збільшенням $iдля наступної ітерації циклу.

Всі вихідні лінії залишаються на конвеєрі, а вихід до терміналу неявний при завершенні програми.

Приклад

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;

Вау! Мені вдалося отримати мою відповідь Рубі, що пройшла повз вашу, прийнявши ваш коментар про побиття інших не-езолангів як виклик! Хороша робота, хоча, +1.
Значення чорнила

@KevinLau Дякую! Назад у вас з 105 зараз. ;-)
AdmBorkBork

Я зателефоную вашим 105, і піднятиму вам 99! : D
Чорнило значення

Більше не замикаючись на побитті Сітківки.
CalculatorFeline

3

С, 278 280 байт

гольф:

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

неозорений:

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

Під час роботи над цим хтось опублікував більш коротку версію, використовуючи sscanf для розбору, а не використовуючи покажчики даних ... приємна!

ОНОВЛЕННЯ: Виявлені пропуски навколо рівних у друкуванні елементів, онлайн-посилання IDE http://ideone.com/KrgRt0 . Зауважте, ця реалізація підтримує від'ємні числа ...


2

Awk, 101 байт

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

Більш зрозуміло:

{
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
}
  • Я встановлюю роздільник поля на все, крім алфавітів, цифр, підкреслення та -. Отже, полями будуть ім'я типу, ім'я змінної та числа.
  • Кількість полів становитиме 1 (для типу) + 1 (для імені) + N (числа) + 1 (порожнє поле після останнього };). Отже, розмір масиву єNF - 3 .
  • Тоді це просто надрукування спеціального рядка для декларації та перекидання цифр.
  • Я повинен призначити FSабо при виклику awk (використання -F), або в BEGINблоці. В інтересах стислості,….

1
Насправді, він FSповинен бути призначений або в, BEGINабо в -Fіншому випадку, він не буде використовуватися для розділення першого рядка, а оскільки є лише 1 рядок введення ...
Роберт Бенсон

@RobertBenson ви праві, тому команда була б 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}', а це 102 байти, не рахуючи awkсебе. Хммм. Чи можу я виключити цитати?
муру

Так, ви можете виключити цитати. Ви іноді перераховуєте його як C+O bytesмісце Cі Oпредставляєте байти відповідно коду та параметрів. Звичайно, я зазвичай просто використовую BEGINблок, тому мені не потрібно думати про це. : p
Роберт Бенсон

2

JavaScript ES6, 134 132 130 129 байт

Збережено 1 байт завдяки Нілу.

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

Не повинно `[${i}] = `+t+";"бути `[${i}] = ${t};`?
Ніл

@Neil Спасибі, збережений байт!
Conor O'Brien

2

bash, 133 129 байт

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

Перша спроба, переконайтеся, що можливо скоротити її.


2

D, 197 , 188 байт

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

або неозорені:

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

Я не знаю D, але ви могли прочитати квадратну дужку, що відкривається, як частину назви? Це врятувало б вам пізніше написати квадратну дужку окремо.
DLosc

2

Юлія, 154 134 101 байт

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])

Це функція, яка приймає рядок і повертає рядок з одним зворотним новим рядком.

Безголівки:

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

Ми визначаємо cяк масив збігів вхідних даних у регулярному виразі -?\w+. Він задає тип, ім'я масиву, а потім кожне значення. Ми зберігаємо nяк довжину c- 2, яка є числом значень. Вихідні дані будуються як інтерпольований тип, ім’я та довжина рядка, поєднані з кожним рядком визначення, розділеним новими рядками. З будь-якої причини, c[]це те саме, що c[1].

Збережено 32 байти за допомогою Dennis!


1

Python 2, 159 байт

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])

Спробуйте в Інтернеті

Дякую Кевіну Лау за кілька пропозицій з гольфу


1

Python 3, 116 байт

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

Розбиває введення на тип, ім’я та список номерів. Після друку заяви, що оголошує масив, друкує елементи, вручну перечисляючи числа, видаляючи зайві розділові знаки, прикріплені до першого та останнього.

Інший підхід у Python 2 склав 122 байти:

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

Ідея полягає evalу переліку чисел як кортеж із комою в кінці, щоб єдине число було розпізнане як тип. Перелічений список номерів надає кортежі у форматі рядків у.


1

PHP, 143 байти

Гольф

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

Безумовно

<?  
$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

Введення приймається через аргумент командного рядка. Зразок:

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

Вихід:

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 байт

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

Це не C, але він використовує sprintfфункцію C-подібну Nah, яка витрачала 4 байти.

Спробуйте в Інтернеті!

          % 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 байт

#(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))))

Я не зміг добре об'єднати awful_array_name[5];та awful_array_name[0] = 7;деталі, щоб вони повторно використовували код: /

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.