Espandere un array C.


36

Nel linguaggio di programmazione C, le matrici sono definite in questo modo:

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

La dimensione dell'array viene dedotta dagli elementi di inizializzazione, che in questo caso è 6. Puoi anche scrivere un array C in questo modo, dimensionandolo esplicitamente e definendo ciascun elemento nell'ordine:

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;

La sfida

È necessario scrivere un programma o una funzione che espande le matrici dal primo al secondo. Dato che stai scrivendo un programma per allungare il codice e ami l'ironia, devi rendere il codice il più breve possibile.

L'input sarà una stringa che rappresenta l'array originale e l'output sarà la definizione dell'array espanso. Puoi tranquillamente supporre che l'input sarà sempre così:

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

"Tipo" e "nome_array" saranno composti interamente da caratteri alfabetici e caratteri di sottolineatura _. Gli elementi dell'elenco saranno sempre un numero compreso tra -2.147.483.648 e 2.147.483.647. Non è necessario gestire gli input in qualsiasi altro formato.

Lo spazio bianco nell'output deve corrispondere esattamente allo spazio bianco nell'output del test, sebbene sia consentita una nuova riga finale.

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;

Presentato in qualsiasi lingua sono incoraggiati, ma punti bonus se si può fare in C.

Classifica:

Ecco una classifica che mostra le risposte migliori:


2
Gli spazi tra l'indice dell'array, il segno di uguale e i valori richiesti nell'output? Ad esempio, sarebbe foo[0]=1;accettabile?
Mego

@Mego Non sarebbe accettabile. È richiesto lo spazio bianco. Lo modificherò in.
DJMcMayhem

Trailing newline consentito?
Luis Mendo,

Sono ammesse funzioni?
Mego

Va bene restituire l'output invece di stamparlo? (in caso di funzioni)
vaultah

Risposte:


12

Pyth, 44 byte

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

Suite di test

Espressione regolare e taglio delle stringhe. Non particolarmente intelligente.

Spiegazione:

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

Questa risposta è la spina nel mio fianco. Pensavo che sarei stato in grado di vincere in vim, ma per la vita di me, non riesco a ottenere gli ultimi 2-3 byte. = D Bella risposta!
DJMcMayhem

28

Tasti Vim, 54, 52, 49 47


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

Spiegazione:

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

Ora il nostro buffer è simile al seguente:

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

e il nostro cursore si trova sull'ultima riga.

Seconda metà:

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

Ora tutto sembra a posto, dobbiamo solo aggiungere la dichiarazione originale dell'array. Quindi facciamo:

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
Ogni volta che leggo un vim-golf, mi rendo conto che tutto il codice che faccio (principalmente i comandi da tastiera nei miei vari editor di GUI) assomiglia molto a questo, e la mia mente si piega per un minuto (Vim è solo turing completo (e più freddo)) : P
gatto,

Non riesco a farlo funzionare - quando scrivo il primo "@q" (di "@ qq @ q"), la macro viene eseguita quindi, e apparentemente corre oltre il previsto, ottenendo cose come int foo[6] = {e terminando con int foo[12(cursore acceso il "2")
LordAro

@LordAro Probabilmente avrei dovuto dirlo. Questo perché c'è già una macro in q, e che gira mentre stai registrando, rovinandola. Ho spiegato come aggirare questo qui: codegolf.stackexchange.com/a/74663/31716
DJMcMayhem

1
@LordAro Oh, duh, so cosa lo sta causando. Ho cambiato df<space>per dWsalvare un byte, ma ho dimenticato che df<space>uscirà dalla macro sulla riga 6, ma dWnon lo fa. Eseguirò il rollback di una revisione. Grazie per la segnalazione!
DJMcMayhem

1
Sebbene questa non sia la risposta più breve, è di gran lunga la più impressionante.
isaacg,

10

Retina, 108 104 100 69 byte

Il conteggio dei byte presuppone la codifica ISO 8859-1.

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

Batti questo, PowerShell ...

Spiegazione del codice

Prima linea: ].+{((\S+ ?)+)

Innanzitutto, dobbiamo mantenere il tipo, il nome dell'array e la parentesi aperta (salva un byte), quindi non li abbiniamo. Così abbiniamo la parentesi di chiusura, qualsiasi numero di caratteri, e una parentesi graffa di apertura: ].+{. Quindi abbiniamo l'elenco dei numeri. Più breve Sono stato in grado di trovare finora è questo: ((\S+ ?)+). Abbiniamo qualsiasi numero di caratteri non-spazio (questo include numeri, possibile segno negativo, ed eventuale virgola), seguito da uno spazio, che può o non può essere lì: \S+ ?. Questo gruppo di personaggi viene quindi ripetuto tutte le volte che è necessario: (\S+ ?)+e inserito nel grande gruppo di cattura. Nota che non abbiniamo la parentesi graffa o il punto e virgola di chiusura. La spiegazione della terza riga spiega perché.

Seconda linea: $#2];$1

Poiché abbiamo abbinato solo una parte dell'input, le parti ineguagliabili saranno ancora lì. Così abbiamo messo la lunghezza della lista dopo la parentesi di apertura senza pari: $#2. Il modificatore di sostituzione #ci aiuta in questo, poiché ci fornisce il numero di corrispondenze effettuate da un determinato gruppo di acquisizione. In questo caso gruppo di acquisizione 2. Quindi mettiamo una parentesi quadra di chiusura e un punto e virgola, e infine tutta la nostra lista.

Con l'input short array[] = {4, 3, 2, 1};, la rappresentazione interna dopo questa sostituzione è:

array corto [4]; 4, 3, 2, 1};

(notare la parentesi graffa e il punto e virgola di chiusura)

Terza riga: +`((\w+[).+;(\S+ )*)(-?\d+).+

Questa è una sezione in loop. Ciò significa che funziona fino a quando nessuno stadio del loop modifica l'input. Primo abbiniamo il nome dell'array, seguito da una parentesi di apertura: (\w+\[). Poi un numero arbitrario di qualsiasi carattere e un punto e virgola: .+;. Poi abbiniamo la lista di nuovo, ma questa volta solo numeri e la virgola dopo ogni numero, che hanno uno spazio li segue: (\S+ )*. Poi abbiamo catturare l'ultimo numero della lista: (-?\d+)e tutti i caratteri rimanenti dietro di esso: .+.

Quarta riga: $1¶$2$#3] = $4;

Abbiamo poi sostituirlo con il nome della matrice e la lista seguito da un ritorno a capo: $1¶. Successivamente, si inserisce il nome di matrice, seguita dalla lunghezza della lista trovato in precedenza, senza che l'ultimo elemento (sostanzialmente list.length - 1): $2$#3. Seguita da una parentesi quadra di chiusura e da un operatore di assegnazione con spazi, seguita dall'ultimo elemento del nostro elenco di numeri:] = $4;

Dopo la prima sostituzione, la rappresentazione interna è simile alla seguente:

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

Si noti che la parentesi graffa di chiusura e il punto e virgola sono scomparsi, grazie alla .+fine della terza riga. Dopo altri tre rimpiazzi, la rappresentazione interna appare così:

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

Dato che non c'è altro da abbinare alla terza riga, la quarta non sostituisce nulla e la stringa viene restituita.

TL; DR: Innanzitutto cambiamo un po 'il formato dell'elenco int. Quindi prendiamo l'ultimo elemento dell'elenco e il nome e li inseriamo dopo l'inizializzazione dell'array. Lo facciamo fino a quando l'elenco int è vuoto. Quindi restituiamo il codice modificato.

Provalo online!


Qualcuno mi ha battuto ... :(
CalculatorFeline

M!`e G`sono simili, ma non del tutto uguali. Stai attento.
CalculatorFeline

La spiegazione della terza riga mi confonde. Il primo oggetto è l'unico senza uno spazio dietro di esso, non l'ultimo.
CalculatorFeline

@CatsAreFluffy Ho provato a cambiare un po 'la formulazione proprio ora. Quello che intendevo era uno spazio che seguiva un numero, non lo precedeva. Immagino di non aver compreso appieno il significato di "dietro". Non dovrei davvero scrivere spiegazioni sul codice alle 2 del mattino.
daavko,

@daavko "Dietro" normalmente significa "dopo" cioè "seguito", in inglese colloquiale. Stavi bene.
Finanzia la causa di Monica il

9

V, 37 byte

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

V è un linguaggio da golf 2D basato su stringhe che ho scritto, progettato su Vim. Funziona a partire da commit 17 .

Spiegazione:

Questa è praticamente una traduzione diretta della mia risposta Vim , anche se significativamente più breve.

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

Quindi abbiamo solo:

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

Poiché questa follia unicode può essere difficile da inserire, puoi creare il file con questo hexdump reversibile:

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.

Questo può essere eseguito installando V e digitando:

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

1
Designed off of vim.2 note: 1. la maggior parte delle persone dice di fromno off of, e 2. perché non esisteva. +1
Rɪᴋᴇʀ

8

C, 215 byte , 196 byte

19 byte salvati grazie a @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 );
}

link:

http://ideone.com/h81XbI

Spiegazione:

Per ottenere il <type> <array_name>, la sscanf()stringa di formato è questa:

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

Per estrarre i valori int dalla stringa int foo[] = {4, 8, 15, 16, 23, 42};, essenzialmente tokenizzo la stringa con questa funzione:

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

dove:

  • i è la stringa di input (a char* )
  • t è l'offset della posizione del puntatore di i
  • x è il reale int analizzato dalla stringa
  • n è il totale dei caratteri consumati, inclusa la cifra trovata

La sscanf()stringa di formato significa questo:

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

Se visualizzi la stringa di input come un array di caratteri:

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

con l' int 4essere posizionato all'indice 13, 8all'indice 16 e così via, ecco come appare il risultato di ogni corsa nel ciclo:

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
puoi evitare di usare strcat concatenando odentro sprintf, tramite %s. Ciò dovrebbe radere attorno a 7 caratteri.
Tucuxi,

@tucuxi Ah, buona cattura. Grazie!
Homersimpson,

7

C, 195 180 byte

195 byte originale:

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
}

Le due scorciatoie stanno usando il mmodificatore per ottenere scanf %sper allocare la propria memoria (salva la dichiarazione di array di caratteri) e usandostrtok (che è anche disponibile di default, senza includere) per fare la parte di analisi dei numeri.


Aggiornamento a 180 byte:

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

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

usi l' idea di bnf679 di aggiungere una stringa per evitare di contare le virgole.


6

Python 3.6 (pre-release), 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]};')

Fa un uso pesante di stringhe a F. .

Versione non golfata:

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, mi sono dimenticato delle corde ad f. Saranno molto utili per il golf!
Morgan Thrapp,

Penso che puoi salvare un byte usando una comprensione dell'elenco invece del normale ciclo
qualcuno con PC

@someonewithpc: no, in realtà aggiungerebbe 1 byte extra
vaultah

5

Rubino, 127 110 108 99 88 byte

Funzione anonima con un singolo argomento come input. Programma completo, legge l'input da STDIN. (Se si esegue il pipe di un file, la nuova riga finale è facoltativa.) Restituisce Stampa la stringa di output.

Ha preso @TimmyD vantandosi della propria soluzione battendo tutti gli altri non-esolang come una sfida, e alla fine ha superato la soluzione (al momento della stesura) di Powershell da 114 byte che avevano pubblicato. Il trucco di Cᴏɴᴏʀ O'Bʀɪᴇɴ con la divisione ]e la giuntura della seconda metà per aiutare i numeri.

Devo usare di più l'operatore splat. È così utile!

Preso in prestito un trucco dalla risposta ES6 di @Neil JavaScript per salvare più byte scansionando le parole invece di usare gsube split..

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

AFAICT il compito è scrivere un programma completo.
vaultah,

@vaultah L'impostazione predefinita per il codice golf è un programma o una funzione
Mego

@Mego: l'OP ha detto "Devi scrivere un programma"
vaultah,

@vaultah normalmente direi che il codice golf mi permette di usare una funzione, ma un programma completo mi ha salvato 2 byte, quindi perché no?
Valore inchiostro

Ooof ... Non penso che PowerShell possa farcela.
Prendi

4

05AB1E , 52 50 47 byte

Codice:

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

Utilizza la codifica CP-1252 . Provalo online! .


1
È arrivato al punto in cui salto tutte le altre risposte solo cercando le risposte 05AB1E. La lingua mi affascina assolutamente.
Peggio ancora,

1
@WorseDoughnut Grazie! Questa è la cosa più bella che qualcuno mi abbia mai detto di 05AB1E :)!
Adnan,

4

JavaScript (ES6), 100 byte

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

Poiché solo le parole sono importanti, questo funziona semplicemente abbinando tutte le parole nella stringa originale, più i segni meno iniziali, quindi costruendo il risultato. (Inizialmente pensavo che avrei usato, replacema si è rivelato essere un'aringa rossa.)


[t,n,...m]quasi una visione mistica
edc65

4

Pyth - 53 50 46 45 44 byte

2 byte salvati grazie a @FryAmTheEggman.

+Jhcz\[+`]lKcPecz\{d\;j.es[ecJd`]kd\=dPb\;)K

Test Suite .


4

Pip , 48 47 byte

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

Prende input da stdin e stampa su stdout.

Spiegazione

Tl; dr: esegue una sostituzione regex, utilizzando i gruppi di acquisizione e una funzione di callback per costruire il risultato.

La qvariabile speciale legge una riga di input. La regex è (\S+)(. = ).(.+)}, che corrisponde a tutto tranne il tipo (incluso lo spazio finale) e il punto e virgola finale. Utilizzando il primo esempio dalla domanda, i gruppi di cattura ottengono foo[, ] = e4, 8, 15, 16, 23, 42 .

La sostituzione è il valore restituito della funzione senza nome {[b#Yd^k']';.n.b.,#y.c.y]}, che viene chiamata con l'intera corrispondenza più i gruppi di acquisizione come argomenti. Pertanto, all'interno della funzione, bottiene il gruppo di acquisizione 1, cil gruppo 2 ed ottiene il gruppo 3.

Costruiamo una lista, i primi tre elementi dei quali saranno "foo[", 6e "]". Per ottenere il 6, abbiamo diviso dsulla variabile incorporata k= ", ", Yankel elenco risultante di numeri interi nella yvariabile per un uso futuro e prendere la lunghezza ( #).']è un personaggio letterale.

Ciò che resta è costruire una serie di stringhe del modulo ";\nfoo[i] = x". Per farlo, abbiamo concatenare i seguenti: ';, n(un built-in per il ritorno a capo), b(1 ° gruppo di cattura), ,#y(equivalente a Python range(len(y))), c(2 ° gruppo di cattura), e y. La concatenazione funziona in modo ordinato su elenchi e intervalli, quindi il risultato è un elenco di stringhe. Mettendo tutto insieme, il valore di ritorno della funzione sarà un elenco come questo:

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

Poiché questo elenco viene utilizzato in un posizionamento di stringa R, viene implicitamente eseguito il cast in una stringa. La conversione da elenco a stringa predefinita in Pip sta concatenando tutti gli elementi:

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

Infine, il risultato (incluso il tipo e il punto e virgola finale, che non sono stati abbinati dal regex e quindi rimangono invariati) viene stampato automaticamente.


4

Perl 5.10, 73 72 68 66 + 1 (per -n switch) = 67 byte

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

Questa è una bella sfida per Perl e la più breve tra le lingue di uso generale finora. Equivalente a

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

4

PowerShell v2 +, 114 105 byte

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

Prende la stringa di input $argsed -replaceè la parentesi quadra senza nulla, quindi esegue uno -splitspazio bianco. Memorizziamo il primo bit in $a, il secondo bit in $b, il =into $ce gli elementi dell'array in $d. Nell'esempio seguente, questo viene archiviato fooin $ae barin $be tutto l'array in $d.

Quindi emettiamo la nostra prima riga con "$a ..."e nel mezzo trasformiamo $dda una matrice di stringhe di forma {1,, 2,... 100};ad una matrice int normale inserendola -joininsieme in una stringa, quindi eseguendola iexdue volte (simile a eval). Archiviamo nuovamente l'array risultante $dprima di chiamare il .lengthmetodo per popolare il numero appropriato tra la []riga di output.

Quindi inviamo $dun ciclo con |%{...}. Ogni iterazione che produciamo "$b..."con una variabile contatore $iracchiusa tra parentesi e il valore corrente $_. La $ivariabile inizia non inizializzata (equivalente a $null) ma ++verrà lanciata su un intprima dell'output, quindi inizierà l'output a 0, tutto prima di incrementare$i per l'iterazione del ciclo successivo.

Tutte le linee di output vengono lasciate sulla pipeline e l'output al terminale è implicito al termine del programma.

Esempio

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;

Meno male! Sono riuscito a ottenere la mia risposta di Ruby superata la tua prendendo il tuo commento sul battere gli altri non-esolang come una sfida! Buon lavoro, però, +1.
Value Ink

@KevinLau Grazie! Torna a te con un 105 ora. ;-)
AdmBorkBork,

Chiamerò il tuo 105 e ti farò guadagnare un 99! : D
Value Ink

Non si chiude più battendo Retina.
Calcolatrice

3

C, 278 280 byte

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

Lavorando su questo, qualcuno ha pubblicato una versione più breve usando sscanf per l'analisi piuttosto che usare i puntatori di dati ... bello!

AGGIORNAMENTO: individuati spazi mancanti attorno agli uguali nella stampa dell'elemento, collegamento IDE online: http://ideone.com/KrgRt0 . Nota che questa implementazione supporta numeri negativi ...


2

Awk, 101 byte

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

Più facilmente:

{
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
}
  • Ho impostato il separatore di campo su tutto tranne alfabeti, cifre, trattino basso e -. Quindi, i campi sarebbero il nome del tipo, il nome della variabile e i numeri.
  • Il numero di campi sarà 1 (per il tipo) + 1 (per il nome) + N (numeri) + 1 (un campo vuoto dopo il trascinamento };). Quindi, la dimensione dell'array èNF - 3 .
  • Quindi stampa solo una riga speciale per la dichiarazione e passa in rassegna i numeri.
  • Ho dovuto assegnare FSsia quando richiamando awk (usando -F) o in un BEGINblocco. Nell'interesse della brevità, ....

1
In realtà, FSdeve essere assegnato in BEGINo utilizzando -Faltrimenti non verrà utilizzato per dividere la prima riga e poiché esiste solo 1 riga di input ...
Robert Benson

@RobertBenson hai ragione, quindi il comando sarebbe 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}', che è di 102 byte senza contare awkse stesso. Hmmm. Posso escludere le virgolette?
muru,

Sì, puoi escludere le virgolette. A volte lo elenchi come C+O bytesdove Ce Orappresentano i byte rispettivamente dal codice e dalle opzioni. Naturalmente di solito uso solo un BEGINblocco, quindi non devo pensarci. : p
Robert Benson,

2

JavaScript ES6, 134 132 130 129 byte

Salvato 1 byte grazie a Neil.

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

Non dovrebbe `[${i}] = `+t+";"essere `[${i}] = ${t};`?
Neil,

@Neil Grazie, salvato un byte!
Conor O'Brien,

2

bash, 133 129 byte

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

Primo tentativo, sicuramente è possibile ridurlo.


2

D, 197 , 188 byte

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

o non golfato:

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

Non conosco D, ma potresti leggere la parentesi quadra di apertura come parte del nome? Ciò ti risparmierebbe di dover scrivere una parentesi quadra separatamente in seguito.
DLosc,

2

Julia, 154 134 101 byte

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

Questa è una funzione che accetta una stringa e restituisce una stringa con una sola nuova riga finale.

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

Definiamo cuna matrice di corrispondenze dell'input sull'espressione regolare -?\w+. Descrive il tipo, il nome dell'array, quindi ciascun valore. Memorizziamo ncome lunghezza di c- 2, che è il numero di valori. L'output è costruito come il tipo, il nome e la stringa di lunghezza interpolati, combinati con ogni riga di definizione separata da newline. Per qualsiasi motivo, c[]è lo stesso di c[1].

Hai salvato 32 byte con l'aiuto di Dennis!


1

Python 2, 159 byte

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

Provalo online

Grazie Kevin Lau per alcuni suggerimenti sul golf


1

Python 3, 116 byte

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

Suddivide l'input nel tipo, nel nome e nell'elenco di numeri. Dopo aver stampato l'array dichiarando, stampa gli elementi enumerando manualmente i numeri, rimuovendo la punteggiatura in eccesso che era attaccata al primo e all'ultimo.

Un approccio diverso in Python 2 è arrivato a 122 byte:

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

L'idea è evalquella di elencare i numeri come una tupla, con una virgola alla fine in modo che un singolo numero venga riconosciuto come un tipo. L'elenco numerato di numeri fornisce le tuple per il formato delle stringhe.


1

PHP, 143 byte

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

L'input viene preso attraverso l'argomento della riga di comando. Campione:

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

Produzione:

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

0

MATL , 68 64 58 byte

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

Questo non è C, ma usa la sprintffunzione simile a C Nah, che stava sprecando 4 byte.

Provalo 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 byte

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

Non sono stato in grado di unire awful_array_name[5];e awful_array_name[0] = 7;parti in modo piacevole in modo che potessero riutilizzare il codice: /

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.