Развернуть массив C


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

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

Leaderboard:

Вот таблица лидеров, показывающая лучшие ответы:


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

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

3
Всякий раз, когда я читаю vim-golf, я осознаю, что все кодирование, которое я делаю (в основном это клавиатурные команды в моих разных графических редакторах), выглядит примерно так, и мой ум как-то изгибается на минуту (Vim просто завершается (и круче)) : P
кошка

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

@LordAro Я, наверное, должен был упомянуть об этом. Это потому, что в q уже есть макрос, который запускается во время записи, запутывая его. Я объяснил, как обойти это здесь: codegolf.stackexchange.com/a/74663/31716
DJMcMayhem

1
@LordAro О, да, я знаю, что вызывает это. Я изменил df<space>на, dWчтобы сохранить байт, но я забыл, что df<space>он выйдет из макроса в строке 6, но dWэто не так. Я откат ревизии. Спасибо что подметил это!
DJMcMayhem

1
Хотя это не самый короткий ответ, он, безусловно, самый впечатляющий.
Исаак

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. В этом #нам помогает модификатор replace , поскольку он дает нам количество совпадений, сделанных конкретной группой захвата. В этом случае группа захвата 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 «Позади» обычно означает «после», то есть «вслед», на разговорном английском языке. Вы были в порядке.
Фонд Моника иск

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.

Поскольку это безумие с юникодом может быть трудно ввести, вы можете создать файл с помощью этой обратимой hexdump:

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!

Golfed:

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

Ungolfed:

/*
 *  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это строка ввода (а 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

Если вы визуализируете входную строку как массив символов:

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 через %s. Это должно побрить около 7 символов.
Tucuxi

@tucuxi Ах, хороший улов. Благодарность!
homersimpson

7

C 195 180 байт

195-байтовый оригинал:

golfed:

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

ungolfed:

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

ungolfed:

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-струны. Это будет очень полезно для гольфа!
Морган Трепп

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

@someonewithpc: нет, это действительно добавило бы 1 дополнительный байт
vaultah

5

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

Анонимная функция с одним аргументом в качестве входных данных. Полная программа, читает входные данные из STDIN. (Если вы передаете файл в файл, завершающий символ новой строки является необязательным.) Возвращает Печать выходной строки.

Мы взяли @TimmyD, хвастаясь своим решением, обойдя все другие не-esolang как вызов, и наконец преодолели (на момент написания) 114-байтовое решение Powershell, которое они опубликовали. Трюк Cᴏɴᴏʀ O'Bʀɪᴇɴ с разделением ]и объединением второй половины, чтобы получить числа, помог.

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

Заимствовал уловку из ответа @ Neil's JavaScript ES6, чтобы сэкономить больше байтов, сканируя слова вместо использования gsubи split..

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

AFAICT задача состоит в том, чтобы написать полную программу.
августа

@vaultah По умолчанию для кода гольф является программа или функция
Mego

@Mego: ОП сказал: «Вы должны написать программу»
vaultah

@vaultah обычно я бы сказал, что Code Golf позволяет мне использовать функцию, но полная программа сэкономила мне 2 байта, так почему бы и нет?
Value Ink

Ooof ... Я не думаю, что 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]}

Принимает ввод из стандартного ввода и печатает в стандартный вывод.

объяснение

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

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переменную для будущего использования и принимаем length ( #).']это буквальный символ.

Осталось построить ряд строк вида ";\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, =в $c, и элементы массива в $d. Для примера ниже, это сохраняет fooв$a и barв $b, а весь массив в$d .

Затем мы выводим нашу первую строку с "$a ..."и в середине преобразования $dиз массива строк формы {1,, 2,... 100};в обычный массив int, -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.
Value Ink

@KevinLau Спасибо! Вернуться на тебя с 105 сейчас. ;-)
AdmBorkBork

Я назову твою 105, и подниму тебе 99! : D
Стоимость чернил

Больше не приближаться к избиению сетчатки.
CalculatorFeline

3

C 278 280 байт

golfed:

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

ungolfed:

/* 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 Спасибо, сохранил байт!
Конор О'Брайен

2

Баш, 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])

Это функция, которая принимает строку и возвращает строку с одним завершающим переводом строки.

Ungolfed:

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 байта с помощью Дениса!


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

Golfed

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

Ungolfed

<?  
$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, но он использует C-подобную sprintfфункцию 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.