Expandir una matriz C

36

En el lenguaje de programación C, las matrices se definen así:

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

El tamaño de la matriz se infiere de los elementos de inicialización, que en este caso es 6. También puede escribir una matriz C de esta manera, dimensionándola explícitamente y luego definiendo cada elemento en orden:

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;

El reto

Debe escribir un programa o función que expanda las matrices de la primera a la segunda. Como está escribiendo un programa para alargar el código y le encanta la ironía, debe hacer que su código sea lo más breve posible.

La entrada será una cadena que representa la matriz original, y la salida será la definición de matriz expandida. Puede asumir con seguridad que la entrada siempre se verá así:

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

"Type" y "array_name" estarán compuestos completamente por caracteres alfabéticos y guiones bajos _. Los elementos de la lista siempre serán un número en el rango de -2,147,483,648 a 2,147,483,647. Las entradas en cualquier otro formato no necesitan ser manejadas.

El espacio en blanco en su salida debe coincidir exactamente con el espacio en blanco en la salida de prueba, aunque se permite una nueva línea final.

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

Se alientan las presentaciones en cualquier idioma, pero puntos de bonificación si puede hacerlo en C.

Tabla de clasificación:

Aquí hay una tabla de clasificación que muestra las principales respuestas:

DJMcMayhem
fuente
2
¿Son los espacios entre el índice de la matriz, el signo igual y los valores requeridos en la salida? Por ejemplo, ¿ foo[0]=1;sería aceptable?
Mego
@Mego Eso no sería aceptable. Se requiere el espacio en blanco. Lo
editaré
¿Nueva línea final permitida?
Luis Mendo
¿Se permiten funciones?
Mego
¿Está bien devolver el resultado en lugar de imprimirlo? (en caso de funciones)
vaultah

Respuestas:

12

Pyth, 44 bytes

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

Banco de pruebas

Expresión regular y corte de cuerdas. No particularmente inteligente.

Explicació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.
isaacg
fuente
Esta respuesta es la espina en mi costado. Pensé que podría ganarlo en vim, pero por mi vida, no puedo quitar los últimos 2-3 bytes. = D ¡Buena respuesta!
DJMcMayhem
28

Vim, 54, 52, 49 47 pulsaciones de teclas


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

Explicación:

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

Ahora nuestro buffer se ve así:

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

y nuestro cursor está en la última línea.

Segunda mitad:

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

Ahora todo se ve bien, solo necesitamos agregar la declaración de matriz original. Entonces hacemos:

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];"
DJMcMayhem
fuente
3
Cada vez que leo un vim-golf, me doy cuenta de que toda la codificación que hago (principalmente comandos de teclado en mis diversos editores de GUI) se parece mucho a esto, y mi mente se inclina por un minuto (Vim se está completando (y más fresco)) : P
gato
No puedo hacer que esto funcione: cuando escribo el primer "@q" (de "@ qq @ q"), la macro se ejecuta entonces, y aparentemente se ejecuta más de lo debido, obteniendo cosas como int foo[6] = {y terminando con int foo[12(cursor en el "2")
LordAro
@ LordAro Probablemente debería haber mencionado eso. Eso es porque ya hay una macro en q, y eso se ejecuta mientras estás grabando, desordenándolo. Le expliqué cómo evitar eso aquí: codegolf.stackexchange.com/a/74663/31716
DJMcMayhem
1
@ LordAro Oh, duh, sé lo que está causando eso. Cambié df<space>a dWpara guardar un byte, pero olvidé que df<space>saldrá de la macro en la línea 6, pero dWno lo hace. Revertiré una revisión. ¡Gracias por señalar eso!
DJMcMayhem
1
Si bien esta no es la respuesta más corta, es de lejos la más impresionante.
isaacg
10

Retina, 108 104 100 69 bytes

El recuento de bytes asume la codificación ISO 8859-1.

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

Batir esto, PowerShell ...

Explicación del código

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

Primero, debemos mantener el tipo, el nombre de la matriz y el corchete de apertura (guarda un byte), para que no coincidamos. Así que coincidir con el corchete de cierre, cualquier número de caracteres, y una llave de apertura: ].+{. Luego hacemos coincidir la lista de números. Más corto que he podido encontrar hasta ahora es la siguiente: ((\S+ ?)+). Hemos partido de cualquier número de caracteres no espaciales (esto incluye números, es posible signo negativo, y es posible coma), seguido de un espacio, que puede o no estar allí: \S+ ?. Este grupo de caracteres se repite tantas veces como sea necesario: (\S+ ?)+y se coloca en el gran grupo de captura. Tenga en cuenta que no coincidimos con la llave de cierre o el punto y coma. La explicación de la tercera línea dice por qué.

Segunda linea: $#2];$1

Como solo coincidimos con una parte de la entrada, las partes no coincidentes seguirán allí. Por eso, pusimos la longitud de la lista después del paréntesis de apertura sin igual: $#2. El modificador de reemplazo #nos ayuda con eso, ya que nos da la cantidad de coincidencias que hizo un grupo de captura en particular. En este caso grupo de captura 2. Luego colocamos un corchete de cierre y un punto y coma, y ​​finalmente nuestra lista completa.

Con entrada short array[] = {4, 3, 2, 1};, la representación interna después de esta sustitución es:

matriz corta [4]; 4, 3, 2, 1};

(tenga en cuenta la llave de cierre y el punto y coma)

Tercera línea: +`((\w+[).+;(\S+ )*)(-?\d+).+

Esta es una sección en bucle. Eso significa que se ejecuta hasta que ninguna etapa del bucle realice un cambio en la entrada. En primer lugar tenemos que coincida con el nombre de la matriz, seguido de un paréntesis de apertura: (\w+\[). A continuación, un número arbitrario de caracteres y un punto y coma: .+;. Luego coincide con la lista de nuevo, pero esta vez sólo números y la coma después de cada número, que tienen un espacio después de ellos: (\S+ )*. Luego capturamos el último número de la lista: (-?\d+)y los caracteres restantes detrás de él: .+.

Cuarta línea: $1¶$2$#3] = $4;

A continuación, sustituirlo por el nombre de la matriz y la lista seguido por un salto de línea: $1¶. A continuación, se puso el nombre de la matriz, seguido por la longitud de lista previamente adaptados, sin el último elemento (esencialmente list.length - 1): $2$#3. Seguido por un operador de cierre y asignación de espacios con espacios, y esto seguido por el último elemento de nuestra lista de números:] = $4;

Después de la primera sustitución, la representación interna se ve así:

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

Tenga en cuenta que la llave de cierre y el punto y coma desaparecieron, gracias al .+final de la tercera línea. Después de tres reemplazos más, la representación interna se ve así:

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

Como no hay nada más que hacer coincidir con la tercera línea, la cuarta no reemplaza nada y se devuelve la cadena.

TL; DR: Primero cambiamos un poco el formato de la lista int. Luego tomamos el último elemento de la lista y el nombre, y los colocamos después de la inicialización de la matriz. Hacemos esto hasta que la lista int esté vacía. Luego devolvemos el código modificado.

Pruébalo en línea!

daavko
fuente
Alguien me ganó ... :(
CalculatorFeline
M!`y G`son similares, pero no exactamente lo mismo. Ten cuidado.
CalculatorFeline
La explicación de la tercera línea me confunde. El primer elemento es el único sin espacio detrás, no el último.
CalculatorFeline
@CatsAreFluffy Intenté cambiar un poco la redacción en este momento. Lo que quise decir fue un espacio que sigue a un número, no lo precede. Supongo que no me di cuenta completamente del significado de "detrás". Realmente no debería escribir explicaciones de código a las 2 am.
daavko
@daavko "Detrás" normalmente significa "después", es decir, "siguiente", en inglés coloquial. Estabas bien
Financia la demanda de Mónica el
9

V, 37 bytes

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

V es un lenguaje de golf 2D basado en cadenas que escribí, diseñado fuera de vim. Esto funciona a partir de commit 17 .

Explicación:

Esta es una traducción directa de mi respuesta vim , aunque significativamente más corta.

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

Entonces solo tenemos:

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

Dado que esta locura unicode puede ser difícil de ingresar, puede crear el archivo con este hexdump reversible:

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.

Esto se puede ejecutar instalando V y escribiendo:

python main.py c_array.v --f=file_with_original_text.txt
DJMcMayhem
fuente
1
Designed off of vim.2 notas: 1. la mayoría de la gente dice que fromno off of, y 2. por qué esto no existe +1
Rɪᴋᴇʀ
8

C, 215 bytes , 196 bytes

¡19 bytes guardados gracias a @tucuxi!

Golfizado:

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

Sin golf:

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

Enlazar:

http://ideone.com/h81XbI

Explicación:

Para obtener el <type> <array_name>, la sscanf()cadena de formato es esta:

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

Para extraer los valores int de la cadena int foo[] = {4, 8, 15, 16, 23, 42};, esencialmente tokenizo la cadena con esta función:

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

dónde:

  • ies la cadena de entrada (a char*)
  • t es el desplazamiento de la ubicación del puntero de i
  • xes el intanálisis real de la cadena
  • n es el total de caracteres consumidos, incluido el dígito encontrado

La sscanf()cadena de formato significa esto:

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

Si visualiza la cadena de entrada como una matriz de caracteres:

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

con el int 4ser ubicado en el índice 13, 8en el índice 16, etc., así es como se ve el resultado de cada ejecución en el 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 ]
Homero Simpson
fuente
1
puedes evitar usar strcat concatenando odentro de sprintf, via %s. Esto debería afeitarse alrededor de 7 caracteres.
tucuxi
@tucuxi Ah, buena captura. ¡Gracias!
homersimpson
7

C, 195 180 bytes

Original de 195 bytes:

golfizado:

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

sin golf:

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
}

Los dos accesos directos están usando el mmodificador para obtener scanf %spara asignar su propia memoria (guarda declarando matrices de caracteres), y están usando strtok(que también está disponible por defecto, sin incluir) para hacer la parte de análisis de números.


Actualización de 180 bytes:

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

sin golf:

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

Utiliza la idea de bnf679 de agregar una cadena para evitar tener que contar comas.

tucuxi
fuente
6

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

Hace un uso intensivo de las cuerdas f .

Versión sin golf:

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]};')
vaultah
fuente
1
Woah, me olvidé de las cuerdas f. ¡Serán súper útiles para el golf!
Morgan Thrapp
Creo que puede guardar un byte utilizando una lista de comprensión en lugar del bucle normal
someonewithpc
@someonewithpc: no, en realidad agregaría 1 byte extra
vaultah
5

Rubí, 127 110 108 99 88 bytes

Función anónima con un solo argumento como entrada.Programa completo, lee la entrada de STDIN. (Si canaliza un archivo, la nueva línea final es opcional). Devuelve Imprime la cadena de salida.

Tomó a @TimmyD alardear de que su solución venció a todos los demás que no eran esolangs como un desafío, y finalmente superó la solución Powershell de 114 bytes (en el momento de la escritura) que habían publicado. El truco de Cᴏɴᴏʀ O'Bʀɪᴇɴ con dividir ]y empalmar la segunda mitad para obtener los números ayudó.

Necesito usar más el operador splat. ¡Es muy útil!

Tomó prestado un truco de la respuesta JavaScript ES6 de @ Neil para guardar más bytes al buscar palabras en lugar de usar gsuby split...

t,n,*l=gets.scan /-?\w+/;i=-1
puts t+" #{n}[#{l.size}];",l.map{|e|n+"[#{i+=1}] = #{e};"}
Tinta de valor
fuente
AFAICT la tarea es escribir un programa completo.
Vaultah
@vaultah El código predeterminado para golf de código es un programa o función
Mego
@Mego: el OP dijo "Debes escribir un programa"
vaultah
@vaultah normalmente diría que el código golf me permite usar una función, pero un programa completo me ahorró 2 bytes, entonces ¿por qué no?
Value Ink el
Ooof ... No creo que PowerShell pueda llegar a eso. Tener un +1
AdmBorkBork
4

05AB1E , 52 50 47 bytes

Código:

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

Utiliza la codificación CP-1252 . Pruébalo en línea! .

Adnan
fuente
1
Llegué al punto en que omito todas las demás respuestas solo buscando sus respuestas 05AB1E. El lenguaje me fascina absolutamente.
WorseDoughnut
1
@WorseDoughnut ¡Gracias! ¡Eso es lo más agradable que alguien me ha dicho sobre 05AB1E :)!
Adnan
4

JavaScript (ES6), 100 bytes

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

Dado que solo las palabras son importantes, esto funciona simplemente haciendo coincidir todas las palabras en la cadena original, más los signos menos a la izquierda, y luego construyendo el resultado. (Originalmente pensé que iba a usar, replacepero resultó ser un arenque rojo).

Neil
fuente
[t,n,...m] casi una visión mística
edc65
4

Pyth - 53 50 46 45 44 bytes

2 bytes guardados gracias a @FryAmTheEggman.

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

Test Suite .

Maltysen
fuente
4

Pip , 48 47 bytes

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

Toma datos de stdin e imprime en stdout.

Explicación

Tl; dr: un reemplazo de expresiones regulares, utilizando grupos de captura y una función de devolución de llamada para construir el resultado.

La qvariable especial lee una línea de entrada. La expresión regular es (\S+)(. = ).(.+)}, que coincide con todo excepto el tipo (incluido el espacio final) y el punto y coma final. Usando el primer ejemplo de la pregunta, los grupos de captura obtienen foo[,] = y4, 8, 15, 16, 23, 42 .

El reemplazo es el valor de retorno de la función sin nombre {[b#Yd^k']';.n.b.,#y.c.y]}, que se llama con toda la coincidencia más los grupos de captura como argumentos. Por lo tanto, dentro de la función, bobtiene el grupo de captura 1, cobtiene el grupo 2 yd obtiene el grupo 3.

Construimos una lista, los tres primeros artículos de los cuales serán "foo[", 6y "]". Para obtener el 6, dividimos den la variable incorporada k= ", ", Yank la lista resultante de enteros en la yvariable para uso futuro, y tomamos la longitud ( #).']Es un carácter literal.

Lo que queda es construir una serie de cadenas de la forma ";\nfoo[i] = x". Para ello, se concatena la siguiente: ';, n(un built-in de nueva línea), b(1er grupo de captura), ,#y(equivalente a Python range(len(y))), c(segundo grupo de captura), y y. La concatenación funciona por elementos en listas y rangos, por lo que el resultado es una lista de cadenas. En conjunto, el valor de retorno de la función será una lista como esta:

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

Dado que esta lista se está utilizando en una Rubicación de cadena , se convierte implícitamente en una cadena. La conversión predeterminada de lista a cadena en Pip está concatenando todos los elementos:

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

Finalmente, el resultado (incluido el tipo y el punto y coma final, que no coincidieron con la expresión regular y, por lo tanto, no se modificaron) se imprime automáticamente.

DLosc
fuente
4

Perl 5.10, 73 72 68 66 + 1 (para el interruptor -n) = 67 bytes

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

Este es un buen desafío para Perl y el más corto entre los lenguajes de uso general hasta ahora. Equivalente a

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

PowerShell v2 +, 114105 bytes

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

Toma la cadena de entrada $argsy -replaceescribe el corchete sin nada, luego realiza un -splitespacio en blanco. Almacenamos el primer bit en $a, el segundo bit en $b, el =into $cy los elementos de la matriz en $d. Para el siguiente ejemplo, esto se almacena fooen$a y bardentro $b, y toda la matriz en$d .

A continuación, salida de la primera línea con "$a ..."y en el medio de transformar $dde una matriz de cadenas de forma {1,, 2,... 100};a una matriz int regular -joining juntos en una sola cadena, a continuación, ejecutar a través de iexdos veces (similar aeval ). Almacenamos esa matriz resultante nuevamente $dantes de llamar al .lengthmétodo para completar el número apropiado entre[] línea de salida.

Luego enviamos a $dtravés de un bucle con |%{...}. Cada iteración se genera "$b..."con una variable de contador $iencapsulada entre paréntesis y el valor actual $_. La $ivariable comienza sin inicializar (equivalente a $null) pero la ++convertirá en un intantes de la salida, por lo que comenzará la salida en 0, todo antes de incrementar$i para la siguiente iteración del bucle.

Todas las líneas de salida se dejan en la tubería, y la salida al terminal está implícita en la terminación del programa.

Ejemplo

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;
AdmBorkBork
fuente
¡Uf! Me las arreglé para que mi respuesta de Ruby superara la tuya al tomar tu comentario sobre vencer a los otros no-esolangs como un desafío. Buen trabajo, sin embargo, +1.
Value Ink el
@KevinLau ¡Gracias! De vuelta a ti con un 105 ahora. ;-)
AdmBorkBork
¡Llamaré a tu 105 y te levantaré un 99! : D
Value Ink el
Ya no te acercas a vencer a Retina.
CalculatorFeline
3

C, 278 280 bytes

golfizado:

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

sin golf:

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

Mientras trabajaba en esto, alguien publicó una versión más corta usando sscanf para el análisis en lugar de usar punteros de datos ... ¡genial!

ACTUALIZACIÓN: Espacios faltantes detectados alrededor de los iguales en la impresión del elemento, enlace en línea IDE: http://ideone.com/KrgRt0 . Tenga en cuenta que esta implementación admite números negativos ...

bnf679
fuente
2

Awk, 101 bytes

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

Más legible:

{
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
}
  • Configuré el separador de campo para todo excepto los alfabetos, los dígitos, el guión bajo y -. Entonces, los campos serían el nombre del tipo, el nombre de la variable y los números.
  • El número de campos será 1 (para el tipo) + 1 (para el nombre) + N (números) + 1 (un campo vacío después del final };). Entonces, el tamaño de la matriz esNF - 3 .
  • Luego solo imprime una línea especial para la declaración y recorre los números.
  • Yo debería asignar FSya sea cuando se invoca awk (usando -F) o en un BEGINbloque. En aras de la brevedad, ...
muru
fuente
1
En realidad, FSdebe asignarse en BEGINo usando, de lo -Fcontrario no se usará para dividir la primera línea, y dado que solo hay 1 línea de entrada ...
Robert Benson
@RobertBenson tienes razón, por lo que el comando sería 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}', que es 102 bytes sin contar awk. Hmmm ¿Puedo excluir las comillas?
Muru
Sí, puede excluir cotizaciones. A veces lo enumera como C+O bytesdónde Cy Orepresenta los bytes del código y las opciones, respectivamente. Por supuesto, generalmente solo uso un BEGINbloque, por lo que no tengo que pensarlo. : p
Robert Benson
2

JavaScript ES6, 134 132 130 129 bytes

Guardado 1 byte gracias 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`
`)
Conor O'Brien
fuente
No debe `[${i}] = `+t+";"ser `[${i}] = ${t};`?
Neil
@Neil Gracias, ¡guardé un byte!
Conor O'Brien el
2

bash, 133 129 bytes

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

Primer intento, seguro que es posible acortarlo.

bnf679
fuente
2

D, 197 , 188 bytes

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 sin golf:

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, ";");
}
Ben Perlin
fuente
No sé D, pero ¿podrías leer el corchete inicial como parte del nombre? Eso le ahorrará tener que escribir un corchete por separado más tarde.
DLosc
2

Julia, 154 134 101 bytes

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

Esta es una función que acepta una cadena y devuelve una cadena con una nueva línea final.

Sin golf:

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

Definimos cser una matriz de coincidencias de la entrada en la expresión regular -?\w+. Incluye el tipo, el nombre de la matriz y luego cada valor. Almacenamosn como la longitud de c- 2, que es el número de valores. La salida se construye como el tipo, el nombre y la longitud de la cadena interpolada, combinada con cada línea de definición separada por líneas nuevas. Por alguna razón, c[]es lo mismo que c[1].

¡Ahorré 32 bytes con la ayuda de Dennis!

Alex A.
fuente
1

Python 2, 159 bytes

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

Pruébalo en línea

Gracias Kevin Lau por algunas sugerencias de golf.

Mego
fuente
1

Python 3, 116 bytes

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

Divide la entrada en el tipo, el nombre y la lista de números. Después de imprimir la declaración de la matriz, imprime los elementos enumerando manualmente a través de los números, eliminando el exceso de puntuación que se adjunta al primero y al último.

Un enfoque diferente en Python 2 salió a 122 bytes:

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

La idea es evalla lista de números como una tupla, con una coma al final para que un solo número sea reconocido como un tipo. La lista enumerada de números proporciona tuplas para formatear en cadena.

xnor
fuente
1

PHP, 143 bytes

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

Sin golf

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

La entrada se toma a través del argumento de la línea de comando. Muestra:

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

Salida:

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

MATL , 68 64 58 bytes

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

Esto no es C, pero usa la sprintffunción tipo C Nah, que estaba desperdiciando 4 bytes.

Pruébalo en línea!

          % 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
Luis Mendo
fuente
0

Clojure, 115 bytes

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

No pude fusionar awful_array_name[5];y awful_array_name[0] = 7;partes para que reutilizaran el código: /

NikoNyrh
fuente