Rozwiń tablicę C.


36

W języku programowania C tablice są zdefiniowane w następujący sposób:

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

Rozmiar tablicy wynika z elementów inicjujących, które w tym przypadku wynoszą 6. Możesz również napisać tablicę C w ten sposób, jawnie zmieniając jej rozmiar, a następnie definiując każdy element w kolejności:

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;

Wyzwanie

Musisz napisać program lub funkcję, która rozwija tablice od pierwszej do drugiej. Ponieważ piszesz program, aby wydłużyć kod i kochasz ironię, musisz go skrócić tak krótko, jak to możliwe.

Dane wejściowe będą ciągiem znaków reprezentującym oryginalną tablicę, a dane wyjściowe będą rozszerzoną definicją tablicy. Możesz bezpiecznie założyć, że dane wejściowe zawsze będą wyglądać następująco:

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

„Type” i „array_name” składają się wyłącznie ze znaków alfabetu i znaków podkreślenia _. Elementami listy zawsze będzie liczba z zakresu od -2 147 483 648 do 2 147 483 647. Wejścia w dowolnym innym formacie nie muszą być obsługiwane.

Biała spacja na wyjściu musi dokładnie pasować do białej spacji na wyjściu testowym, chociaż dozwolony jest końcowy znak nowej linii.

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

Zgłoszenia w dowolnym języku są zachęcane, ale punkty bonusowe, jeśli możesz to zrobić w C.

Tabela liderów:

Oto tabela liderów przedstawiająca najlepsze odpowiedzi:


2
Czy spacje między indeksem tablicy, znakiem równości i wartościami wymaganymi w danych wyjściowych? Na przykład, czy foo[0]=1;byłby do przyjęcia?
Mego

@Mego To byłoby nie do przyjęcia. Biała spacja jest wymagana. Zmienię to.
DJMcMayhem

Końcowa nowa linia jest dozwolona?
Luis Mendo

Czy funkcje są dozwolone?
Mego

Czy można zwracać dane wyjściowe zamiast je drukować? (w przypadku funkcji)
vaultah 15.04.16

Odpowiedzi:


12

Pyth, 44 bajty

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

Zestaw testowy

Wyrażenie regularne i odcinanie łańcucha. Niezbyt sprytnie.

Wyjaśnienie:

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

Ta odpowiedź jest moim cierniem. Myślałem, że uda mi się wygrać w vimie, ale przez całe moje życie nie mogę oderwać ostatnich 2-3 bajtów. = D Ładna odpowiedź!
DJMcMayhem

28

Vim, 54, 52, 49 47 klawiszy


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

Wyjaśnienie:

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

Teraz nasz bufor wygląda następująco:

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

a nasz kursor znajduje się w ostatniej linii.

Druga połowa:

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

Teraz wszystko wygląda dobrze, wystarczy dodać oryginalną deklarację tablicową. Więc robimy:

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
Ilekroć czytam vim-golfa, zdaję sobie sprawę, że całe kodowanie, które robię (głównie polecenia klawiaturowe w moich różnych edytorach GUI) wygląda podobnie do tego, a mój umysł trochę się ugina (Vim jest po prostu kompletny (i fajniejszy)) : P
cat

Nie mogę tego uruchomić - kiedy piszę pierwsze „@q” (z „@ qq @ q”), makro działa wtedy i najwyraźniej działa dalej niż powinno, uzyskując rzeczy podobne int foo[6] = {i kończące się int foo[12(kursor na „2”)
LordAro

@ LordAro Prawdopodobnie powinienem o tym wspomnieć. Dzieje się tak, ponieważ w q znajduje się już makro, które działa podczas nagrywania, co psuje go. Wyjaśniłem, jak to obejść tutaj: codegolf.stackexchange.com/a/74663/31716
DJMcMayhem

1
@ LordAro O rany, wiem co to powoduje. Zmieniłem df<space>na, dWaby zapisać bajt, ale zapomniałem, że df<space>wyrwie się z makra w linii 6, ale dWnie robi tego. Cofam wersję. Dzięki za zwrócenie na to uwagi!
DJMcMayhem

1
Chociaż nie jest to najkrótsza odpowiedź, jest zdecydowanie najbardziej imponująca.
isaacg

10

Siatkówka, 108 104 100 69 bajtów

Liczba bajtów zakłada kodowanie ISO 8859-1.

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

Pokonaj to, PowerShell ...

Wyjaśnienie kodu

Pierwsza linia: ].+{((\S+ ?)+)

Po pierwsze, musimy zachować typ, nazwę tablicy i nawias otwierający (to oszczędza bajt), więc nie pasujemy do nich. Więc dopasować wspornik zamykający dowolną liczbę znaków, a otwór nawias klamrowy: ].+{. Następnie dopasowujemy listę numerów. Najkrótsza udało mi się znaleźć do tej pory to: ((\S+ ?)+). Pasuje do dowolnej liczby znaków niż kosmiczne (w tym numery możliwe znak ujemny i możliwe przecinek), a następnie za pomocą przestrzeni, które mogą lub nie mogą być tam: \S+ ?. Ta grupa znaków jest następnie powtarzana tyle razy, ile potrzeba: (\S+ ?)+i umieszczana w dużej grupie przechwytywania. Pamiętaj, że nie pasujemy do zamykającego nawiasu klamrowego ani średnika. Wyjaśnienie trzeciego wiersza mówi dlaczego.

Druga linia: $#2];$1

Ponieważ dopasowaliśmy tylko część danych wejściowych, niedopasowane części nadal tam będą. Więc umieścić długość listy po nawiasie otwierającym niedopasowanej: $#2. Modyfikator zastępowania #pomaga nam w tym, ponieważ daje nam liczbę dopasowań wykonanych przez konkretną grupę przechwytującą. W tym przypadku grupa przechwytująca2 . Następnie dodajemy nawias zamykający i średnik, a na koniec całą naszą listę.

Z wejściem short array[] = {4, 3, 2, 1}; wewnętrzna reprezentacja po tym zastąpieniu to:

krótka tablica [4]; 4, 3, 2, 1};

(zwróć uwagę na zamykający nawias klamrowy i średnik)

Trzecia linia: +`((\w+[).+;(\S+ )*)(-?\d+).+

To jest sekcja zapętlona. Oznacza to, że działa, dopóki żaden stopień w pętli nie zmieni danych wejściowych. Najpierw musimy dopasować nazwę tablicy, a następnie za pomocą uchwytu otwierającego: (\w+\[). Potem dowolną ilość dowolnych znaków i średnik: .+;. Następnie dopasować listę ponownie, ale tym razem tylko liczby i przecinek po każdym numerze, który ma miejsce po nich: (\S+ )*. Następnie uchwycić ostatni numer w liście: (-?\d+)i wszelkie pozostałe znaki za nim: .+.

Czwarta linia: $1¶$2$#3] = $4;

Następnie zastąp go nazwą tablicy i listy zakończoną nową linią: $1¶. Następnie kładziemy nazwę tablicy, a następnie długości poprzednio dopasowane listy, bez ostatniego elementu (zasadniczo list.length - 1) $2$#3. Po nim nawias zamykający i operator przypisania ze spacjami, a następnie ostatni element naszej listy liczb:] = $4;

Po pierwszej wymianie wewnętrzna reprezentacja wygląda następująco:

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

Zauważ, że zamykające się nawiasy klamrowe i średnik zniknęły dzięki .+końcowi trzeciej linii. Po trzech kolejnych zamianach wewnętrzna reprezentacja wygląda następująco:

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

Ponieważ nic nie pasuje do trzeciej linii, czwarta nic nie zastępuje, a łańcuch jest zwracany.

TL; DR: Najpierw nieco zmienimy format listy int. Następnie bierzemy ostatni element listy i nazwę i umieszczamy je po inicjalizacji tablicy. Robimy to, dopóki lista int nie będzie pusta. Następnie zwracamy zmieniony kod.

Wypróbuj online!


Ktoś mnie pobił .... :(
CalculatorFeline

M!`i G`są podobne, ale nie do końca takie same. Bądź ostrożny.
CalculatorFeline

Wyjaśnienie trzeciego wiersza mnie dezorientuje. Pierwszy przedmiot jest jedynym bez spacji, a nie ostatnim.
CalculatorFeline

@CatsAreFluffy Właśnie próbowałem nieco zmienić brzmienie. Miałem na myśli spację po liczbie, a nie poprzedzającą ją. Chyba nie w pełni zrozumiałem znaczenie „za”. Naprawdę nie powinienem pisać objaśnień kodu o 2 w nocy.
daavko

@daavko „Behind” zwykle oznacza „po”, czyli „po”, w potocznym języku angielskim. Było dobrze
Pozew funduszu Moniki

9

V, 37 bajtów

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

V to napisany przeze mnie napisany w 2D język golfowy oparty na łańcuchach. Działa to od zatwierdzenia 17 .

Wyjaśnienie:

Jest to prawie bezpośrednie tłumaczenie mojej odpowiedzi vima , choć znacznie krótsze.

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

Mamy po prostu:

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

Ponieważ trudno jest wprowadzić to szaleństwo w trybie Unicode, możesz utworzyć plik za pomocą tego odwracalnego zrzutu heksadecymalnego:

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.

Można to uruchomić, instalując V i wpisując:

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

1
Designed off of vim.2 notatki: 1. większość ludzi mówi , że fromnie off of, i 2. dlaczego tak nie było. +1
Rɪᴋᴇʀ

8

C, 215 bajtów , 196 bajtów

19 bajtów zapisanych dzięki @tucuxi!

Gra w golfa:

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

Nie golfowany:

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

Połączyć:

http://ideone.com/h81XbI

Wyjaśnienie:

Aby uzyskać <type> <array_name>, sscanf()ciąg formatu jest następujący:

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

Aby wyodrębnić wartości int z ciągu int foo[] = {4, 8, 15, 16, 23, 42};, zasadniczo tokenizuję ciąg za pomocą tej funkcji:

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

gdzie:

  • ito ciąg wejściowy (a char*)
  • t to przesunięcie położenia wskaźnika na i
  • xto rzeczywista intparsowana z ciągu
  • n to łączna liczba zużytych znaków, w tym znaleziona cyfra

sscanf()Ciąg formatu oznacza to:

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

Jeśli wizualizujesz ciąg wejściowy jako tablicę znaków:

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

z int 4byciem zlokalizowanym pod indeksem 13, 8pod indeksem 16 i tak dalej, tak wygląda wynik każdego uruchomienia w pętli:

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
możesz uniknąć używania strcat, łącząc owewnątrz sprintf, przez %s. Powinno to ogolić około 7 znaków.
tucuxi 18.04.16

@tucuxi Ah, dobry chwyt. Dzięki!
homersimpson 18.04.16

7

C, 195 180 bajtów

195-bajtowy oryginał:

grał w golfa:

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

bez golfa:

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
}

Oba skróty używają mmodyfikatora, aby uzyskać od skanów %sprzydział własnej pamięci (zapisuje deklarowanie tablic znaków) i używają strtok(która jest domyślnie dostępna, bez uwzględnienia) do wykonania analizy składni liczbowej.


Aktualizacja 180-bajtowa:

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

bez golfa:

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

Wykorzystuje pomysł bnf679 dołączania do ciągu, aby uniknąć konieczności liczenia przecinków.


6

Python 3.6 (wersja wstępna), 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]};')

Często korzysta z struny typu F. .

Wersja bez golfa:

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, zapomniałem o f-stringach. Będą one bardzo przydatne do gry w golfa!
Morgan Thrapp,

Myślę, że możesz zapisać bajt, używając rozumienia listy zamiast normalnej pętli
someonewithpc

@someonewithpc: nope, faktycznie
dodałby

5

Ruby, 127 110 108 99 88 bajtów

Funkcja anonimowa z jednym argumentem wejściowym.Pełny program odczytuje dane wejściowe ze STDIN. (Jeśli wpiszesz plik do potoku, końcowy znak nowej linii jest opcjonalny). Zwraca Drukuje ciąg wyjściowy.

@TimmyD chwalił się swoim rozwiązaniem pokonując wszystkie inne nie-esolangi jako wyzwanie, i wreszcie pokonał (w chwili pisania) 114 bajtowe rozwiązanie Powershell, które opublikowali. Sztuczka Cᴏɴᴏʀ O'Bʀɪᴇɴ z dzieleniem się] i drugiej połowy w celu uzyskania liczb.

Muszę więcej korzystać z operatora splat. To takie przydatne!

Wypożyczył sztuczkę z odpowiedzi JavaScript ES6 @ Neil, aby zaoszczędzić więcej bajtów, skanując w poszukiwaniu słów zamiast używać gsubi split...

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

AFAICT zadaniem jest napisanie pełnego programu.
vaultah 15.04.16

@vaultah Domyślnym kodem do golfa jest program lub funkcja
Mego

@Mego: OP powiedział „Musisz napisać program”
vaultah

@vaultah normalnie powiedziałbym, że kod golf pozwala mi korzystać z funkcji, ale pełny program oszczędził mi 2 bajty, więc czemu nie?
Wartość tuszu

Hej ... Nie sądzę, że PowerShell może do tego dojść. Zdobądź +1
AdmBorkBork 18.04.16

4

05AB1E , 52 50 47 bajtów

Kod:

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

Wykorzystuje kodowanie CP-1252 . Wypróbuj online! .


1
Doszło do tego, że pomijam wszystkie inne odpowiedzi, szukając tylko odpowiedzi 05AB1E. Język absolutnie mnie fascynuje.
WorseDoughnut 18.04.16

1
@WorseDoughnut Dziękujemy! To najładniejsza rzecz, jaką ktoś mi powiedział o 05AB1E :)!
Adnan

4

JavaScript (ES6), 100 bajtów

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

Ponieważ tylko słowa są ważne, działa to po prostu dopasowując wszystkie słowa w oryginalnym ciągu, plus poprzedzające znaki minus, a następnie budując wynik. (Początkowo myślałem, że zamierzam użyć, replaceale okazało się, że to czerwony śledź.)


[t,n,...m]prawie mistyczna wizja
edc65 16.04.16


4

Pip , 48 47 bajtów

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

Pobiera dane wejściowe ze standardowego wejścia i drukuje na standardowe wyjście.

Wyjaśnienie

Tl; dr: Wykonuje zamianę wyrażenia regularnego, używając grup przechwytywania i funkcji zwrotnej do skonstruowania wyniku.

qSpecjalna zmienna czyta wiersz wejścia. Wyrażenie regularne to (\S+)(. = ).(.+)}, które pasuje do wszystkiego oprócz typu (w tym spacji końcowej) i końcowego średnika. Korzystając z pierwszego przykładu z pytania, grupy przechwytujące otrzymują foo[:] = i4, 8, 15, 16, 23, 42 .

Zastąpienie jest wartością zwracaną funkcji bez nazwy {[b#Yd^k']';.n.b.,#y.c.y]}, która jest wywoływana z całym dopasowaniem plus grupy przechwytywania jako argumenty. Zatem w ramach funkcji bpobiera grupę przechwytywania 1, cgrupę 2 id grupę 3.

Budujemy listy, pierwsze trzy pozycje, które będą "foo[", 6i "]". Aby uzyskać 6, podzieliliśmy dsię na wbudowaną zmienną k= ", ", Yprzekartkowaliśmy wynikową listę liczb całkowitych na yzmienną do przyszłego wykorzystania, i wzięliśmy długość ( #).']to dosłowny charakter.

Pozostaje zbudować serię ciągów formy ";\nfoo[i] = x". Aby to zrobić, możemy złączyć co następuje: ';, n(wbudowany do nowej linii), b(grupa 1-ty capture), ,#y(odpowiednik Python range(len(y))), c(grupa 2-ty capture), a y. Łączenie działa itemowo na listach i zakresach, więc wynikiem jest lista ciągów. Podsumowując, zwracaną wartością funkcji będzie lista taka jak ta:

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

Ponieważ ta lista jest używana w Rzastępowaniu ciągów , jest ona domyślnie rzutowana na ciąg. Domyślna konwersja list-to-string w Pip łączy wszystkie elementy:

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

Ostatecznie wynik (w tym typ i końcowy średnik, które nie zostały dopasowane przez wyrażenie regularne, a zatem pozostają niezmienione) jest drukowany automatycznie.


4

Perl 5.10, 73 72 68 66 + 1 (dla przełącznika -n) = 67 bajtów

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

To miłe wyzwanie dla Perla i jak najkrótsze spośród języków ogólnego przeznaczenia. Równoważny

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

4

PowerShell v2 +, 114 105 bajtów

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

Pobiera ciąg wejściowy $argsi -replacenawias kwadratowy bez niczego, a następnie wykonuje znak -splitspacji. Pierwszy bit przechowujemy w $a, drugi bit w $b, elementy =w $ci elementy tablicy w $d. W poniższym przykładzie przechowuje się foow $ai bardo$b , a cała tablica w $d.

Następnie wyjście z nasza pierwsza linia "$a ..."w środku przekształcić $dz tablicą ciągów postaci {1,, 2,... 100};do zwykłego int tablicy przez -joining go ze sobą w jeden ciąg, a następnie uruchomić go poprzez iexdwa razy (podobnie jak eval). Przechowujemy wynikową tablicę z powrotem $dprzed wywołaniem .lengthmetody w celu wypełnienia odpowiedniej liczby pomiędzy[] wierszem wyjściowym.

Następnie wysyłamy $dza pomocą pętli |%{...}. Każdą iterację wyprowadzamy "$b..."za pomocą zmiennej przeciwnej $izawartej w nawiasach i bieżącej wartości $_. $iZmienna zaczyna niezainicjowanymi (odpowiednik $null), ale ++rzuci go do intprzed wyjściem, więc będzie rozpocząć produkcję na 0wszystko przed zwiększany $ido następnej iteracji pętli.

Wszystkie linie wyjściowe są pozostawione w potoku, a dane wyjściowe do terminala są niejawne przy zakończeniu programu.

Przykład

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;

Uff! Udało mi się zdobyć odpowiedź Ruby na twoje, biorąc pod uwagę twój komentarz na temat pokonania innych nie-esolangów! Dobra robota, +1.
Wartość tuszu

@KevinLau Thanks! Wracam do ciebie z 105 teraz. ;-)
AdmBorkBork

Zadzwonię do twojego 105 i podniosę ci 99! : D
Wartość tuszu

Już nie zbliża się do pokonania Retiny.
CalculatorFeline

3

DO, 278 280 bajtów

grał w golfa:

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

bez golfa:

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

Podczas pracy nad tym ktoś opublikował krótszą wersję używającą sscanf do analizowania zamiast używania wskaźników danych ... ładna!

AKTUALIZACJA: Wykryto brakujące spacje wokół równych w drukowanym elemencie, internetowy link IDE: http://ideone.com/KrgRt0 . Uwaga: ta implementacja obsługuje liczby ujemne ...


2

Awk, 101 bajtów

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

Bardziej czytelnie:

{
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
}
  • Ustawiam separator pól na wszystko oprócz alfabetów, cyfr, znaku podkreślenia i -. Tak więc pola byłyby nazwą typu, nazwą zmiennej i liczbami.
  • Liczba pól będzie wynosić 1 (dla typu) + 1 (dla nazwy) + N (liczby) + 1 (puste pole po trailingu };). Rozmiar tablicy to NF - 3.
  • Następnie drukuje specjalny wiersz deklaracji i zapętla liczby.
  • I należy przypisać FSzarówno podczas wywoływania awk (za pomocą -F) albo w BEGINbloku. W trosce o zwięzłość….

1
W rzeczywistości FSnależy go przypisać albo BEGINużyć, -Finaczej nie zostanie użyty do podzielenia pierwszego wiersza, a ponieważ jest tylko 1 wiersz danych wejściowych ...
Robert Benson

@RobertBenson masz rację, więc polecenie brzmiałoby 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 bajtów, nie licząc awksię. Hmmm. Czy mogę wykluczyć cytaty?
muru

Tak, możesz wykluczyć cytaty. Czasami podajesz go jako C+O bytesgdzie Ci Oreprezentujesz bajty odpowiednio z kodu i opcji. Oczywiście na ogół używam tylko BEGINbloku, więc nie muszę o tym myśleć. : p
Robert Benson

2

JavaScript ES6, 134 132 130 129 bajtów

Zapisano 1 bajt dzięki Neilowi.

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

Nie powinno `[${i}] = `+t+";"być `[${i}] = ${t};`?
Neil

@Neil Thanks, zapisany bajt!
Conor O'Brien

2

bash, 133 129 bajtów

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

Pierwsza próba, na pewno można ją skrócić.


2

D, 197,188 bajtów

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

lub bez golfa:

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

Nie znam D, ale czy mógłbyś odczytać otwierający nawias kwadratowy jako część nazwy? Pozwoliłoby to zaoszczędzić konieczności późniejszego pisania nawiasu kwadratowego.
DLosc

2

Julia, 154 134 101 bajtów

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

Jest to funkcja, która akceptuje ciąg i zwraca ciąg z pojedynczym końcowym znakiem nowej linii.

Nie golfowany:

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

Definiujemy, cże jest tablicą dopasowań danych wejściowych wyrażenia regularnego -?\w+. Uwzględnia typ, nazwę tablicy, a następnie każdą wartość. Przechowujemy njako długośćc - 2, która jest liczbą wartości. Dane wyjściowe są konstruowane jako interpolowany ciąg typu, nazwy i długości, połączony z każdą linią definicji oddzieloną znakami nowej linii. Z jakiegokolwiek powodu c[]jest taki sam jak c[1].

Zapisano 32 bajty z pomocą Dennisa!


1

Python 2, 159 bajtów

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

Wypróbuj online

Dzięki Kevin Lau za sugestie dotyczące gry w golfa


1

Python 3, 116 bajtów

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

Dzieli dane wejściowe na typ, nazwę i listę liczb. Po wydrukowaniu deklaracji macierzy drukuje elementy, ręcznie wyliczając liczby, usuwając nadmiar interpunkcji dołączonej do pierwszej i ostatniej.

Inne podejście w Pythonie 2 wyszło na 122 bajty:

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

Chodzi o evallistę liczb jako krotkę z przecinkiem na końcu, aby pojedynczy numer był rozpoznawany jako typ. Wymieniona lista liczb zawiera krotki w formacie ciągu.


1

PHP, 143 bajty

Grał w golfa

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

Bez golfa

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

Dane wejściowe są pobierane za pomocą argumentu wiersza poleceń. Próba:

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

Wydajność:

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 bajtów

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

To nie jest C, ale używa sprintffunkcji podobnej do C Nah, która marnowała 4 bajty.

Wypróbuj online!

          % 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 bajtów

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

Nie byłem w stanie ładnie połączyć awful_array_name[5];i awful_array_name[0] = 7;części, aby ponownie użyły kodu: /

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.