Jimmy essas matrizes para baixo

23

Meu colega de trabalho, Jimmy , é meio novo no C / C ++. Ele também é um tipo de aluno lento. Agora, para ser justo, seu código sempre compila, mas ele tem alguns hábitos realmente desleixados. Por exemplo, todo mundo sabe que você pode definir uma matriz como esta:

int spam[] = {4, 8, 15, 16, 23, 42};

Todo mundo que é, exceto Jimmy. Ele está convencido de que a única maneira de criar uma matriz é assim:

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

Eu continuo consertando isso para ele na revisão de código, mas ele não aprende. Então, preciso que você escreva uma ferramenta que faça isso automaticamente por ele quando ele cometer¹.

O desafio

Quero que você escreva um programa completo ou uma função que aceite uma seqüência de linhas múltiplas como entrada e produza a versão mais compacta da matriz C. A entrada sempre seguirá este formato, incluindo o espaço em branco:

identifier_one identifier_two[some_length];
identifier_two[0] = some_number;
identifier_two[1] = some_number;
identifier_two[2] = some_number;
...
identifier_two[some_length - 1] = some_number;

Em suma, a entrada será sempre válida e bem definida C. Mais detalhadamente:

Todos os identificadores serão compostos apenas de letras e sublinhados. O comprimento sempre será pelo menos um e nunca haverá índices ausentes ou fora dos limites. Você também pode assumir que os índices estão em ordem. Por exemplo:

foo bar[3];
bar[0] = 1
bar[2] = 9;

foo bar[1];
bar[0] = 1;
bar[1] = 3;

e

foo bar[3];
bar[2] = 9;
bar[0] = 1
bar[1] = 3

são todas entradas inválidas e podem causar um comportamento indefinido no seu envio. Você também pode assumir que todos os números serão números decimais válidos, negativos ou positivos. A entrada não terá espaços estranhos. A saída deve sempre seguir este formato, incluindo o espaço em branco:

identifier_one identifier_two[] = {n1, n2, n3, ...};

Aqui estão alguns dados de amostra:

Input:
spam eggs[10];
eggs[0] = 0;
eggs[1] = 4;
eggs[2] = 8;
eggs[3] = -3;
eggs[4] = 3;
eggs[5] = 7;
eggs[6] = 888;
eggs[7] = 555;
eggs[8] = 0;
eggs[9] = -2;

Output:
spam eggs[] = {0, 4, 8, -3, 3, 7, 888, 555, 0, -2};

Input:
char ans[2];
ans[0] = 52;
ans[1] = 50;

Output:
char ans[] = {52, 50};

Input:
blah_blah quux[1];
quux[0] = 105;

Output:
blah_blah quux[] = {105};

Você pode levar sua entrada e saída em qualquer formato razoável, como STDIN / STDOUT, argumentos de função e valor de retorno, leitura e gravação de arquivos etc. Lacunas padrão se aplicam. A resposta mais curta em bytes vence!


Isso é agressivo-passivo e uma péssima idéia. Você não recebeu essa ideia de mim.

DJMcMayhem
fonte
8
Minhas desculpas a Jimmy
DJMcMayhem
6
Relacionado.
DLosc 21/09/16
@DLosc Ah, é isso que Jimmy está usando em seu script de pré-confirmação!
Bergi 21/09/16
9
Claro que Jimmy não é um jogador de código.
precisa saber é o seguinte
Esse desafio realmente atrapalhou meus Jimmies .
DanTheMan

Respostas:

8

Vim, 43 36 bytes

Você não precisa fornecer um script para Jimmy, apenas ensine-o a usar um editor de texto adequado. (retornos literais para maior clareza)

:%s/.*=//|%s/;\n/,/<cr><cr>
3wcf ] = {<esc>
$s};
m-chrzan
fonte
Agradável! Nesse caso específico, <C-a>é menor que t], o que é um pequeno truque divertido. Além disso, acho que você tecnicamente precisa de 2, <cr>pois pede confirmação.
DJMcMayhem
As respostas do Vim para os desafios padrão do código de golfe devem ser pontuadas em bytes.
Martin Ender
Além disso, norm df=é mais curto ques/.*=//g
DJMcMayhem
1
Além disso, 3wC] = {<esc>é menor que <C-a>di]$s = {<esc>.
DJMcMayhem
1
@ Geobits Onde está o seu Emacs responder?
Neil
7

CJam, 43 36 bytes

qN/('[/~;"[] = {"@{S/W=W<}%", "*"};"

Exemplo Online

Explicação:

qN/                                     |Read all lines to array
   ('[/~;                               |slice first line left of [
         "[] = {"                       |add formatting to stack
                 @                      |rotate to remaining lines
                  {      }%             |for each line in array
                   S/W=                 |split after last space
                       W<               |remove last character (;)
                           ", "*        |insert ", " to array
                                "};"    |add formatting

Um grande obrigado a Martin Ender pelas melhorias na minha primeira resposta CJam.

Linus
fonte
6

JavaScript (ES6), 65 64 63 bytes

s=>`${s.split`[`[0]}[] = {${s.match(/-?\d+(?=;)/g).join`, `}};`
Huntro
fonte
5

Retina , 30 28 bytes

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

\d+];¶.+ 
] = {
;¶.+=
,
;
};

Experimente online!

Explicação

Usaremos a seguinte entrada como exemplo:

spam eggs[4];
eggs[0] = 0;
eggs[1] = 4;
eggs[2] = 8;
eggs[3] = -3;

Estágio 1

\d+];¶.+ 
] = {

Observe que há um espaço à direita na primeira linha.

Começamos combinando um número seguido de ];e um avanço de linha e, em seguida, tudo até o último espaço na próxima linha. Esta partida só pode ser encontrada no final da primeira linha (devido à ];). Tudo isso é substituído por ] = {. Ou seja, ele transforma nosso exemplo de entrada em:

spam eggs[] = {0;
eggs[1] = 4;
eggs[2] = 8;
eggs[3] = -3;

Etapa 2

;¶.+=
,

Agora combinamos tudo, de um ;até o =na próxima linha e substituímos por um ,. Isso transforma a string em:

spam eggs[] = {0, 4, 8, -3;

Etapa 3

;
};

Tudo o que resta é fixar o final e fazemos isso substituindo o único restante ;por };:

spam eggs[] = {0, 4, 8, -3};
Martin Ender
fonte
5

Julia, 112 108 105 Bytes

f(s)=string(split(s,'[')[1],"[] = {",join([m[1] for m in [eachmatch(r"= *(-?\d+)",s)...]],", "),"};")

Explicação

string(                                                         # build output string
split(s,'[')[1],                                                # get declaration (e.g. spam eggs)
"[] = {",                                                       # add [] = {
join(                                                           # collect numbers
    [m[1] for m in [eachmatch(r"= *(-?\d+)",s)...]],            # regex out (signed) numbers
    ", "),                                                      # and join comma separated
"};"                                                            # add };
)                                                               # close string(

Bytes salvos substituindo collect (eachmatch ()) por [eachmatch () ...] e por um regex menor

nyro_0
fonte
Olá, seja bem-vindo ao PPCG! Parece uma ótima primeira resposta. +1 de mim. Como o desafio declara " Você pode receber sua entrada e saída em qualquer formato razoável ", é possível remover o espaço após o separador de vírgulas na eachmatchchamada de função para obter uma saída menos bonita e -1 byte. Eu nunca programei em Julia, mas você pode achar interessante este post: Dicas para jogar golfe em Julia . Mais uma vez bem-vindo e aproveite a sua estadia. :)
Kevin Cruijssen
1
muito obrigado pelas suas amáveis ​​palavras :) O PPCG parecia divertido de se investigar, então pensei em tentar. Escolheu Julia para esta resposta, uma vez que não estava presente ainda
nyro_0
O uso matchallprovavelmente seria mais curto que o splatting eachmatch.
Alex A.
Tentei usar o matchall primeiro, mas ele não me deixou usar grupos regex (a parte entre parênteses em que estou particularmente interessado) em oposição a eachmatch. (ou eu não poderia encontrá-lo na documentação?)
nyro_0
3

Lua, 121 bytes.

function g(s)print(s:gmatch('.-%[')()..'] = {'..s:gsub('.-\n','',1):gsub('.-([%d.-]+);\n?','%1, '):gsub(',%s+$','};'))end

Explicado

function g(s)
    print(                              -- Print, Self Explaintry.
        s:gmatch('.-%[')()..'] = {'     -- Find the 'header', match the first line's class and assignment name (everything up to the 'n]') and append that. Then, append ] = {.
                                        -- In the eggs example, this looks like; 'spam eggs[] = {' now
        ..                              -- concatenate...
        s:gsub('.-\n','',1)             -- the input, with the first line removed.
        :gsub('.-([%d.-]+);\n?','%1, ') -- Then that chunk is searched, quite boringly, a number followed by a semicolon, and the entire string is replaced with an array of those,
                                        -- EG, '1, 2, 3, 4, 5, 6, '
        :gsub(',%s+$','};')          -- Replace the final ', ' (if any) with a single '};', finishing our terrifying combination
    )
end
ATaco
fonte
3

Lote, 160 bytes

@echo off
set/ps=
set s=%s:[=[] = {&rem %
set r=
:l
set t=
set/pt=
if "%t%"=="" echo %r%};&exit/b
set t=%t:* =%
set r=%r%%s%%t:~2,-1%
set s=, 
goto l

Nota: A linha set s=,termina com um espaço. Recebe entrada em STDIN. Essa linha estranha 3 recebe a entrada (por exemplo, int spam[6];e muda [para [] = {&remresultando na set s=int spam[] = {&rem 6];qual, em seguida, é interpretada como duas instruções set s=int spam[] = {e rem 6];a última delas é um comentário. Em seguida, para cada linha, excluímos o texto até o primeiro espaço (porque você pode use =em um padrão e a correspondência não seja gananciosa) e extraia o valor.

Neil
fonte
3

C, 121 bytes

n=2;main(i){for(;putchar(getchar())^91;);for(printf("] = {");~scanf("%*[^=]%*c%d",&i);n=0)printf(", %d"+n,i);puts("};");}
orlp
fonte
3

Python 112 111

Muito direto para mim, por favor, sugira qualquer melhoria que vier à mente.

def f(l):
 a,*b=l.split('\n')
 return a[:a.index('[')]+'[] = {'+', '.join(r.split(' = ')[1][:-1]for r in b)+'};'


# TEST

lines = """spam eggs[10];
eggs[0] = 0;
eggs[1] = 4;
eggs[2] = 8;
eggs[3] = -3;
eggs[4] = 3;
eggs[5] = 7;
eggs[6] = 888;
eggs[7] = 555;
eggs[8] = 0;
eggs[9] = -2;"""
print (f(lines))
assert f(lines) == 'spam eggs[] = {0, 4, 8, -3, 3, 7, 888, 555, 0, -2};'
Caridorc
fonte
De uma olhada rápida, vejo que há um espaço em branco inútil [:-1] for.
Yytsi 22/09/16
2

05AB1E , 31 30 28 bytes

žh-|vy#¤¨ˆ\}¨… = ¯ïžuDÀÀ‡';J

Explicação

žh-¨                            # remove numbers and ";" from first input
    |v      }                   # for each of the rest of the inputs
      y#                        # split on spaces
        ¤¨                      # take the last element (number) minus the last char (";") 
          ˆ\                    # store in global array and throw the rest of the list away
             … =                # push the string " = "
                 ¯ï             # push global array and convert to int
                   žuDÀÀ‡       # replace square brackets of array with curly ones
                         ';     # push ";"
                           J    # join everything and display

Experimente online!

Guardou um byte graças a Adnan

Emigna
fonte
žuDÀÀem vez de „[]„{}salvar um byte :).
Adnan
@ Adnan: Certo, boa captura!
Emigna
2

Java 7, 159 158 149 154 bytes

String c(String[]a){a[0]=a[0].split("\\d")[0]+"] = {\b";for(String i:a)a[0]+=i.split("= [{]*")[1];return a[0].replace(";",", ").replaceFirst("..$","};");}

Vários bytes salvos graças a @cliffroot .

Ungolfed & código de teste:

Experimente aqui.

class M{
  static String c(String[] a){
    a[0] = a[0].split("\\d")[0] + "] = {\b";
    for(String i : a){
      a[0] += i.split("= [{]*")[1];
    }
    return a[0].replace(";", ", ").replaceFirst("..$", "};");
  }

  public static void main(String[] a){
    System.out.println(c(new String[]{ "spam eggs[10];", "eggs[0] = 0;", "eggs[1] = 4;",
      "eggs[2] = 8;", "eggs[3] = -3;", "eggs[4] = 3;", "eggs[5] = 7;", "eggs[6] = 888;",
      "eggs[7] = 555;", "eggs[8] = 0;", "eggs[9] = -2;" }));
    System.out.println(c(new String[]{ "char ans[2]", "ans[0] = 52;", "ans[1] = 50;" }));
    System.out.println(c(new String[]{ "blah_blah quux[1];", "quux[0] = 105;" }));
  }
}

Saída:

spam eggs[] = {0, 4, 8, -3, 3, 7, 888, 555, 0, -2};
char ans[] = {52, 50};
blah_blah quux[] = {105};
Kevin Cruijssen
fonte
1
poucos bytes salvos String c(String[]a){a[0]=a[0].split("\\d")[0]+"]={ \b";for(String i:a)a[0]+=i.split("=[{]*")[1];return a[0].replace(';',',').replaceFirst(".$","};");}
cliffroot 21/09
@cliffroot Obrigado! De fato, alguns truques legais, como reutilizar Stringo parâmetro e substituir o último caractere por"};"); vez de um "")+"};";.
Kevin Cruijssen
2

Perl, 42 + 2 ( -0p) = 44 bytes

s%\d+].*%] = {@{[join",",/(-?\d+);/g]}};%s

Precisa -pe -0sinalizadores para executar. Por exemplo :

perl -0pe 's%\d+].*%] = {@{[join",",/(-?\d+);/g]}};%s' <<< "blah_blah quux[1];
quux[0] = 105;"
dada
fonte
1

Gelatina , 27 bytes

Ỵ©ḢḟØDṖ“ = {”®Ḳ€Ṫ€Ṗ€j⁾, ⁾};

Experimente online!

Explicação

Ỵ         Split into lines
 ©Ḣ       Take the first one, store the others in ®
   ḟØD    Remove digits
      Ṗ   Remove trailing ;

“ = {”    Print a literal string

®         Recall the remaining lines
 Ḳ€       Split each into words
   Ṫ€     Keep each last word
     Ṗ€   Remove each trailing ;

j⁾,       Join by “, ”
    ⁾};   Literal “};”
Lynn
fonte
1

sed 51

1s,\[.*,[] = {,
:
N
s,\n.*= ,,
s/;/, /
$s/, $/};/
t
Riley
fonte
1

Java, 106 bytes

A manipulação de strings em Java é um inferno, como sempre.

a->a[0].join("",a).replaceAll(";\\w+\\[\\d+\\] = ",", ").replaceAll("\\d+\\], ","] = {").replace(";","};")

Esta é uma resposta pura regex. Faça uma única concatenada Stringe executereplaceXxx até que esteja tudo bem.

Testando e não destruído:

import java.util.function.Function;

public class Main {

  public static void main(String[] args) {
    Function<String[], String> f = a ->
        String.join("", a)                          // I think this would join. Not sure, though. Golfed into a[0].join because static members are accessible from instances.
            .replaceAll(";\\w+\\[\\d+\\] = ", ", ") // replace with regex
            .replaceAll("\\d+\\], ", "] = {")       // replace with regex
            .replace(";", "};");                    // replace no regex

    String[] spam = {
      "int spam[6];",
      "spam[0] = 4;",
      "spam[1] = 8;",
      "spam[2] = 15;",
      "spam[3] = 16;",
      "spam[4] = 23;",
      "spam[5] = 42;"
    };
    test(f, spam, "int spam[] = {4, 8, 15, 16, 23, 42};");

    String[] eggs = {
      "spam eggs[10];",
      "eggs[0] = 0;",
      "eggs[1] = 4;",
      "eggs[2] = 8;",
      "eggs[3] = -3;",
      "eggs[4] = 3;",
      "eggs[5] = 7;",
      "eggs[6] = 888;",
      "eggs[7] = 555;",
      "eggs[8] = 0;",
      "eggs[9] = -2;"
    };
    test(f, eggs, "spam eggs[] = {0, 4, 8, -3, 3, 7, 888, 555, 0, -2};");

    String[] ans = {
      "char ans[2];",
      "ans[0] = 52;",
      "ans[1] = 50;"
    };
    test(f, ans, "char ans[] = {52, 50};");

    String[] quux = {
      "blah_blah quux[1];",
      "quux[0] = 105;"
    };
    test(f, quux, "blah_blah quux[] = {105};");

  }

  static void test(Function<String[], String> f, String[] input, String expected) {
    System.out.printf("Result:   %s%nExpected: %s%n", f.apply(input), expected);
  }
}
Olivier Grégoire
fonte
0

Gelatina , 33 bytes

ỴḊḲ€Ṫ€K⁾;,yṖ“{“};”j
ỴḢḟØDṖ,⁾ =,ÇK

TryItOnline

Quão?

ỴḊḲ€Ṫ€K⁾;,yṖ“{“};”j - Link 1, parse and reform the values, same input as the Main link
Ỵ                   - split on line feeds
 Ḋ                  - dequeue (remove the first line)
  Ḳ€                - split each on spaces
    Ṫ€              - tail each (get the numbers with trailing ';')
      K             - join on spaces
       ⁾;,          - ";,"
          y         - map (replace ';' with ',')
           Ṗ        - pop (remove the last ',')
            “{“};”  - list of strings ["{","};"]
                  j - join (making "{" + "n0, n1, ,n2, ..." + "};")

ỴḢḟØDṖ,⁾ =,ÇK - Main link, takes one argument, the multiline string
Ỵ             - split on line feeds
 Ḣ            - head (just the first line)
   ØD         - digits yield "0123456789"
  ḟ           - filter out
     Ṗ        - pop (remove the trailing ';')
      ,   ,   - pair
       ⁾ =    - the string " ="
           Ç  - call the previous Link (1)
            K - join on spaces (add the space after the '=')
Jonathan Allan
fonte
Down eleitor - o que há de errado com isso?
Jonathan Allan
0

JavaScript, 125 bytes

Eu sei que é mais longo que os outros, mas eu realmente queria usar eval. Apenas por diversão.

f=function(s){m=/^(\w+ )(\w+).*?(;.*)/.exec(s)
eval("var "+m[2]+"=new Array()"+m[3]+'alert(m[1]+m[2]+"={"+eval(m[2])+"};")')}

Para executar, cole o seguinte aqui :

s='int spam[6];\
spam[0] = 4;\
spam[1] = 8;\
spam[2] = 15;\
spam[3] = 16;\
spam[4] = 23;\
spam[5] = 42;'
f=function(s){m=/^(\w+ )(\w+).*?(;.*)/.exec(s)
eval("var "+m[2]+"=new Array()"+m[3]+'alert(m[1]+m[2]+"={"+eval(m[2])+"};")')}
f(s)
mbomb007
fonte
0

Haxe, 234 bytes

function R(L:Array<String>){var S=L[0];var W=S.indexOf(" ");var T=S.substr(0,W),M=S.substring(W+1,S.indexOf("["));var r=[for(i in 1...L.length)L[i].substring(L[i].lastIndexOf(" ")+1,L[i].length-1)].join(', ');return'$T $M[] = {$r};';}

Nomes de funções longos eliminaram isso: D

Experimente as caixas de teste aqui !

Yytsi
fonte
0

V , 25 , 24 bytes

3wC] = {òJd2f $s, òhC};

Experimente online! Isso contém um <esc>caractere não imprimível , então aqui está um hexdump:

0000000: 3377 435d 203d 207b 1bf2 4a64 3266 2024  3wC] = {..Jd2f $
0000010: 732c 20f2 6843 7d3b                      s, .hC};

Explicação:

3w                              "Move forward 3 words
  C     <esc>                   "Delete everything until the end of the line, and enter this text:
   ] = {                        "'] = {'
             ò         ò        "Recursively:
              J                 "  Join these two lines (which enters a space)
               d                "  Delete everything until you
                2f              "  (f)ind the (2)nd space
                   $            "  Move to the end of this line
                    s           "  Delete a character, and enter:
                     ,          "  ', '
                                "
                        h       "Move one character to the left
                         C      "Delete everything until the end of the line, and enter this text:
                          };    "'};'
DJMcMayhem
fonte