Expanda uma matriz C


36

Na linguagem de programação C, as matrizes são definidas assim:

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

O tamanho da matriz é inferido a partir dos elementos de inicialização, que neste caso são 6. Você também pode escrever uma matriz C dessa maneira, dimensionando-a explicitamente e definindo cada elemento na ordem:

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;

O desafio

Você deve escrever um programa ou função que expanda matrizes da primeira maneira para a segunda. Como você está escrevendo um programa para aumentar o código e adora a ironia, deve torná-lo o mais curto possível.

A entrada será uma sequência que representa a matriz original e a saída será a definição de matriz expandida. Você pode assumir com segurança que a entrada sempre será assim:

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

"Type" e "array_name" serão compostos inteiramente de caracteres do alfabeto e sublinhados _. Os elementos da lista sempre serão um número no intervalo de -2.147.483.648 a 2.147.483.647. Entradas em qualquer outro formato não precisam ser manipuladas.

O espaço em branco na sua saída deve corresponder exatamente ao espaço em branco na saída de teste, embora uma nova linha à direita seja permitida.

Teste de E / S:

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

Envios em qualquer idioma são encorajados, mas pontos de bônus se você puder fazê-lo em C.

Entre os melhores:

Aqui está um cabeçalho mostrando as principais respostas:


2
Os espaços entre o índice da matriz, o sinal de igual e os valores necessários na saída? Por exemplo, seria foo[0]=1;aceitável?
Mego

@ Mega Isso não seria aceitável. O espaço em branco é obrigatório. Vou editar que no.
DJMcMayhem

Nova linha à direita permitida?
Luis Mendo

As funções são permitidas?
Mego

É bom retornar a saída em vez de imprimi-la? (no caso de funções)
vaultah 15/04

Respostas:


12

Pitão, 44 ​​bytes

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

Suíte de teste

Expressão regular e corte de cordas. Não é particularmente inteligente.

Explicação:

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

Esta resposta é o espinho do meu lado. Eu pensei que seria capaz de vencê-lo no vim, mas para a minha vida, não consigo tirar os últimos 2-3 bytes. = D Boa resposta!
DJMcMayhem

28

Vim, 54, 52, 49 47 pressionamentos de tecla


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

Explicação:

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

Agora nosso buffer fica assim:

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 nosso cursor está na última linha.

Segundo tempo:

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

Agora tudo parece bom, basta adicionar a declaração de matriz original. Então fazemos:

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
Sempre que leio um vim-golf, percebo que todo o código que faço (principalmente os comandos de teclado nos meus diversos editores de GUI) se parece muito com isso, e minha mente meio que se dobra por um minuto (o Vim está completo (e mais legal)) : P
cat

Não consigo fazer isso funcionar - quando digito o primeiro "@q" (de "@ qq @ q"), a macro é executada e, aparentemente, é mais além do que deveria, obtendo coisas como int foo[6] = {e terminando com int foo[12(cursor em the "2")
LordAro 16/04

@ LordAro Eu provavelmente deveria ter mencionado isso. Isso porque já existe uma macro em q, e é executada enquanto você grava, estragando tudo. Expliquei como contornar isso aqui: codegolf.stackexchange.com/a/74663/31716
DJMcMayhem

1
@ LordAro Oh, duh, eu sei o que está causando isso. Mudei df<space>para dWsalvar um byte, mas esqueci que df<space>a macro sairá da linha 6, mas dWnão. Vou reverter uma revisão. Obrigado por apontar isso!
DJMcMayhem

1
Embora essa não seja a resposta mais curta, é de longe a mais impressionante.
Isaacg

10

Retina, 108 104 100 69 bytes

A contagem de bytes assume a codificação ISO 8859-1.

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

Bata isso, PowerShell ...

Explicação do código

Primeira linha: ].+{((\S+ ?)+)

Primeiro, precisamos manter o tipo, o nome do array e o colchete de abertura (ele salva um byte), para não coincidir com eles. Então nós combinamos o colchete de fechamento, qualquer número de caracteres, e uma chave de abertura: ].+{. Então combinamos a lista de números. Mais curta que eu tenho sido capaz de encontrar até agora é a seguinte: ((\S+ ?)+). Nós combinar com qualquer número de caracteres não-espaço (isso inclui números, possível sinal negativo, e possível vírgula), seguido por um espaço, que pode ou não estar lá: \S+ ?. Esse grupo de caracteres é repetido quantas vezes for necessário: (\S+ ?)+e colocado no grande grupo de captura. Observe que não correspondemos à chave ou ponto e vírgula de fechamento. A explicação da terceira linha diz o porquê.

Segunda linha: $#2];$1

Como apenas correspondemos a uma parte da entrada, as partes não correspondentes ainda estarão lá. Então nós colocamos o comprimento da lista após o colchete de abertura inigualável: $#2. O modificador de substituição #nos ajuda com isso, pois fornece o número de correspondências que um grupo de captura específico fez. Nesse caso, o grupo de captura2 . Em seguida, colocamos um colchete e um ponto e vírgula e, finalmente, toda a lista.

Com entrada short array[] = {4, 3, 2, 1}; , a representação interna após essa substituição é:

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

(observe a chave e o ponto e vírgula de fechamento)

Terceira linha: +`((\w+[).+;(\S+ )*)(-?\d+).+

Esta é uma seção em loop. Isso significa que ele é executado até que nenhum estágio do loop faça uma alteração na entrada. Em primeiro lugar, coincidir com o nome da matriz, seguida por um sinal de abertura: (\w+\[). Em seguida, um número arbitrário de caracteres e um ponto e vírgula: .+;. Então nós combinamos a lista novamente, mas desta vez apenas números e a vírgula depois de cada número, que têm um espaço de segui-los: (\S+ )*. Então nós capturar o último número na lista: (-?\d+)e quaisquer caracteres restantes por trás dele: .+.

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

Em seguida, substituí-lo com o nome da matriz e lista, seguido por uma nova linha: $1¶. Em seguida, vamos colocar o nome da matriz, seguido pelo comprimento da lista previamente combinada, sem o último elemento (essencialmente list.length - 1): $2$#3. Seguido por um operador de colchete e atribuição com espaços, seguido pelo último elemento da nossa lista de números:] = $4;

Após a primeira substituição, a representação interna fica assim:

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

Observe que a chave de fechamento e o ponto e vírgula desapareceram, graças ao .+no final da terceira linha. Após mais três substituições, a representação interna fica assim:

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

Como não há mais nada a combinar com a terceira linha, a quarta não substitui nada e a string é retornada.

TL; DR: Primeiro, alteramos um pouco o formato da lista int. Depois, pegamos o último elemento da lista e o nome e os colocamos após a inicialização do array. Fazemos isso até que a lista int esteja vazia. Em seguida, devolvemos o código alterado.

Experimente online!


Alguém me venceu ... :(
CalculatorFeline

M!`e G`são semelhantes, mas não são iguais. Seja cuidadoso.
CalculatorFeline

A explicação da terceira linha me confunde. O primeiro item é o único sem espaço atrás dele, não o último.
CalculadoraFeline

@CatsAreFluffy Tentei mudar um pouco a redação agora. O que eu quis dizer foi um espaço após um número, não o precedendo. Acho que não percebi completamente o significado de "por trás". Eu realmente não deveria escrever explicações de código às 2 da manhã.
Daavko 17/04

@daavko "Atrás" normalmente significa "depois", ou seja, "seguindo", em inglês coloquial. Você estava bem.
Fund Monica's Lawsuit

9

V, 37 bytes

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

V é uma linguagem de golfe 2D baseada em cordas que eu escrevi, projetada fora do vim. Isso funciona a partir do commit 17 .

Explicação:

Esta é praticamente uma tradução direta da minha resposta vim , embora significativamente menor.

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

Então nós apenas temos:

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

Como essa loucura unicode pode ser difícil de entrar, você pode criar o arquivo com este hexdump reversível:

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.

Isso pode ser executado instalando V e digitando:

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

1
Designed off of vim.2 notas: 1. a maioria das pessoas diz que fromnão off of, e 2. por que isso não existia? +1
R

8

C, 215 bytes , 196 bytes

19 bytes salvos graças ao @tucuxi!

Golfe:

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

Ligação:

http://ideone.com/h81XbI

Explicação:

Para obter o <type> <array_name>, a sscanf()string de formato é 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 extrair os valores int da string int foo[] = {4, 8, 15, 16, 23, 42};, eu tokenizo essencialmente a string com esta função:

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

Onde:

  • ié a sequência de entrada (a char*)
  • t é o deslocamento da localização do ponteiro de i
  • xé o real intanalisado da sequência
  • n é o total de caracteres consumidos, incluindo o dígito encontrado

A sscanf()cadeia de formato significa isso:

%*            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 você visualizar a sequência de entrada como uma matriz de caracteres:

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

com o local int 4no índice 13, 8no índice 16 e assim por diante, é assim que o resultado de cada execução no loop se parece:

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
você pode evitar o uso do strcat concatenando odentro do sprintf, via %s. Isso deve raspar cerca de 7 caracteres.
Tucuxi

@ tucuxi Ah, boa captura. Obrigado!
Homer Simpson

7

C, 195 180 bytes

Original de 195 bytes:

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
}

Os dois atalhos estão usando o mmodificador para fazer com que os scanfs %saloquem sua própria memória (salva declarando matrizes de caracteres) e usando strtok(que também está disponível por padrão, sem inclusões) para executar a parte de análise de número.


Atualização 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);}

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

Usa a idéia de bnf679 de anexar a uma string para evitar ter que contar vírgulas.


6

Python 3.6 (pré-lançamento), 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]};')

Faz uso pesado de strings .

Versão não destruída:

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
Uau, eu esqueci as strings. Serão super úteis para o golfe!
Morgan Thrapp

Eu acho que você pode salvar um byte usando uma compreensão de lista em vez do ciclo normal de
someonewithpc

@someonewithpc: Não, isso seria realmente adicionar 1 byte extra
vaultah

5

Ruby, 127 110 108 99 88 bytes

Função anônima com um único argumento como entrada. Programa completo, lê a entrada do STDIN. (Se você canalizar um arquivo, a nova linha à direita é opcional.) Retorna Imprime a sequência de saída.

O @TimmyD se gabou de sua solução, superando todos os outros não-esolangs como um desafio e, finalmente, superou a (no momento da redação) da solução Powershell de 114 bytes que eles haviam publicado. O truque de Cᴏɴᴏʀ O'Bʀɪᴇɴ com divisão ]e emenda do segundo tempo para ajudar os números.

Preciso usar mais o operador splat. É tão útil!

Emprestado um truque da resposta JavaScript ES6 do @ Neil para economizar mais bytes pesquisando palavras em vez de usar gsub e split..

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

AFAICT a tarefa é escrever um programa completo.
vaultah

@vaultah O padrão para o golfe código é uma função programa ou
Mego

@Mego: o OP disse "Você deve escrever um programa"
vaultah

@vaultah normalmente, eu diria que o código golf me permite usar uma função, mas um programa completo me salvou 2 bytes, então por que não?
Valor Ink

Ooof ... Eu não acho que o PowerShell possa fazer isso. Tenha um +1
AdmBorkBork

4

05AB1E , 52 50 47 bytes

Código:

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

Usos a codificação CP-1252 . Experimente online! .


1
Chegou ao ponto em que pulo todas as outras respostas apenas procurando as respostas 05AB1E. A linguagem absolutamente me fascina.
WorseDoughnut

1
@WorseDoughnut Thank you! Essa é a coisa mais legal que alguém já me disse sobre 05AB1E :)!
21416 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``

Como apenas as palavras são importantes, isso funciona apenas combinando todas as palavras da sequência original, além de sinais de menos, e criando o resultado. (Eu originalmente pensei que iria usar, replacemas isso acabou sendo um arenque vermelho.)


[t,n,...m]quase uma visão mística
edc65


4

Pip , 48 47 bytes

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

Pega a entrada de stdin e imprime em stdout.

Explicação

Tl; dr: faz uma substituição de regex, usando grupos de captura e uma função de retorno de chamada para construir o resultado.

A qvariável especial lê uma linha de entrada. O regex é (\S+)(. = ).(.+)}, que corresponde a tudo, exceto o tipo (incluindo o espaço à direita) e o ponto e vírgula final. Usando o primeiro exemplo da questão, os grupos de captura obter foo[, ] = e4, 8, 15, 16, 23, 42 .

A substituição é o valor de retorno da função sem nome {[b#Yd^k']';.n.b.,#y.c.y]}, chamada com toda a correspondência mais os grupos de captura como argumentos. Assim, dentro da função, bobtém o grupo de captura 1, cobtém o grupo 2 e dobtém o grupo 3.

Nós construímos uma lista, os três primeiros itens dos quais serão "foo[", 6, e "]". Para obter 6isso, dividimos da variável interna k= ", ", Yank a lista resultante de números inteiros na yvariável para uso futuro e pegamos o comprimento ( #).']é um caractere literal.

O que resta é construir uma série de seqüências de caracteres do formulário ";\nfoo[i] = x". Para fazê-lo, nós concatenar o seguinte: ';, n(um built-in de nova linha), b(1º grupo de captura), ,#y(equivalente a Python range(len(y))), c(2º grupo de captura), e y. A concatenação funciona itemwise em listas e intervalos, portanto, o resultado é uma lista de cadeias. Juntando tudo, o valor de retorno da função será uma 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]
]

Como essa lista está sendo usada em um Rposicionamento de cadeia , ela é convertida implicitamente em uma cadeia. A conversão padrão de lista em string no Pip está concatenando todos os elementos:

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

Por fim, o resultado (incluindo o tipo e o ponto e vírgula final, que não foram correspondidos pelo regex e, portanto, permanecem inalterados) é impresso automaticamente.


4

Perl 5.10, 73 72 68 66 + 1 (para a opção -n) = 67 bytes

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

Esse é um bom desafio para o Perl e o menor entre os idiomas de uso geral até agora. Equivalente a

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

4

PowerShell v2 +, 114 105 bytes

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

Pega a string de entrada $argse -replacecoloca o colchete sem nada, depois executa um -splitespaço em branco. Armazenamos o primeiro bit em $a, o segundo bit em $b, o =into $ce os elementos da matriz em $d. Para o exemplo abaixo, isso armazena foodentro $ae bardentro de $btoda a matriz $d.

Em seguida, produzimos nossa primeira linha com "$a ..."e no meio a transformação $dde uma matriz de strings de forma {1,, 2,... 100};para uma matriz int regular -join, juntando-a em uma string e executando-a iexduas vezes (semelhante a eval). Armazenamos a matriz resultante novamente $dantes de chamar o .lengthmétodo para preencher o número apropriado entre os []na linha de saída.

Em seguida, enviamos $dum loop com |%{...}. Cada iteração é gerada "$b..."com uma variável de contador $iencapsulada entre colchetes e o valor atual $_. A $ivariável começa não inicializada (equivalente a $null), mas a ++converterá em intantes da saída, para que inicie a saída às 0, antes de incrementar $ipara a próxima iteração do loop.

Todas as linhas de saída são deixadas no pipeline e a saída para o terminal está implícita na finalização do programa.

Exemplo

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;

Uau! Consegui fazer com que a minha resposta do Ruby fosse passada pela sua, desafiando o seu comentário sobre derrotar os outros não-esolangs! Bom trabalho, no entanto, +1.
Valor Ink

@KevinLau Thanks! De volta a você com 105 agora. ;-)
AdmBorkBork 15/04

Vou ligar para o seu 105 e aumentar para você 99! : D
Value Ink

Não mais se aproximando de bater em Retina.
CalculatorFeline

3

C, 278 280 bytes

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

Enquanto trabalhava nisso, alguém postou uma versão mais curta usando o sscanf para a análise, em vez de usar ponteiros de dados ... uma ótima!

ATUALIZAÇÃO: Espaços ausentes localizados ao redor dos iguais na impressão do elemento, link online do IDE: http://ideone.com/KrgRt0 . Observe que esta implementação suporta números negativos ...


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}

Mais 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
}
  • Defino o separador de campos para tudo, exceto alfabetos, dígitos, sublinhado e - . Portanto, os campos seriam o nome do tipo, o nome da variável e os números.
  • O número de campos será 1 (para o tipo) + 1 (para o nome) + N (números) + 1 (um campo vazio após o final };). Portanto, o tamanho da matriz éNF - 3 .
  • Depois, basta imprimir uma linha especial para a declaração e passar pelos números.
  • Eu devo atribuir FSao invocar o awk (using -F) ou em um BEGINbloco. No interesse da brevidade,….

1
Na verdade, FSdeve ser atribuído tanto no BEGINou utilizar -Fde outra forma ele não será usado para dividir a primeira linha, e uma vez que há apenas 1 linha de entrada ...
Robert Benson

@RobertBenson você está certo, então o comando seria 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 é de 102 bytes sem contar awk. Hummm. Posso excluir as aspas?
muru

Sim, você pode excluir aspas. Às vezes, você o lista como C+O bytesonde Ce Orepresenta os bytes do código e das opções, respectivamente. É claro que geralmente uso apenas um BEGINbloco, então não preciso pensar nisso. : p
Robert Benson

2

JavaScript ES6, 134 132 130 129 bytes

Guardado 1 byte graças 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`
`)

Não deveria `[${i}] = `+t+";"ser `[${i}] = ${t};`?
Neil

@ Neil Obrigado, salvou um byte!
Conor O'Brien

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

Primeira tentativa, com certeza é possível diminuí-la.


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

ou ungolfed:

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

Eu não sei D, mas você poderia ler o colchete de abertura como parte do nome? Isso pouparia a necessidade de escrever um colchete separadamente mais 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 é uma função que aceita uma sequência e retorna uma sequência com uma única nova linha à direita.

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

Definimos ccomo uma matriz de correspondências da entrada na expressão regular -?\w+. Ele abrange o tipo, nome da matriz e cada valor. Armazenamos ncomo o comprimento dec - 2, que é o número de valores. A saída é construída como o tipo, nome e sequência de comprimento interpolados, combinados com cada linha de definição separada por novas linhas. Por qualquer motivo, c[]é o mesmo que c[1].

Economizou 32 bytes com a ajuda de Dennis!


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

Experimente online

Obrigado Kevin Lau por algumas sugestões de golfe


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 a entrada no tipo, nome e lista de números. Depois de imprimir a declaração da matriz, imprime os elementos enumerando manualmente os números, removendo o excesso de pontuação anexada ao primeiro e ao último.

Uma abordagem diferente no Python 2 chegou 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

A idéia é evallistar os números como uma tupla, com uma vírgula no final, para que um único número seja reconhecido como um tipo. A lista enumerada de números fornece tuplas para o formato de sequência.


1

PHP, 143 bytes

Golfe

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

A entrada é obtida através do argumento da linha de comandos. Amostra:

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

Saída:

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 bytes

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

Isso não é C, mas usa a sprintffunção semelhante a C Nah, que estava desperdiçando 4 bytes.

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

Eu não era capaz de bem fundir awful_array_name[5];e awful_array_name[0] = 7;peças de modo que eles re-utilização de código: /

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.