Jimmy estas matrices abajo

23

Mi compañero de trabajo, Jimmy es un poco nuevo en C / C ++. También es un poco lento para aprender. Ahora, para ser justos, su código siempre se compila, pero tiene algunos hábitos realmente descuidados. Por ejemplo, todo el mundo sabe que puede definir una matriz como esta:

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

Todos los que están, excepto Jimmy. Está convencido de que la única forma de hacer una matriz es así:

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

Sigo arreglando esto para él en la revisión de código, pero no aprenderá. Así que necesito que escribas una herramienta que automáticamente haga esto por él cuando se compromete¹.

El reto

Quiero que escriba un programa completo o una función que tome una cadena multilínea como entrada y genere la versión más compacta de la matriz C. La entrada siempre seguirá este formato, incluido el espacio en blanco:

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;

En resumen, la entrada siempre será válida y bien definida C. Con más detalle:

Todos los identificadores estarán compuestos solo por letras y guiones bajos. La longitud siempre será al menos uno, y nunca habrá ningún índice faltante o fuera de límites. También puede suponer que los índices están en orden. Por ejemplo:

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

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

y

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

son entradas no válidas y pueden causar un comportamiento indefinido en su envío. También puede suponer que todos los números serán números decimales válidos, negativos o positivos. La entrada no tendrá espacios extraños. La salida siempre debe seguir este formato, incluido el espacio en blanco:

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

Aquí hay algunos datos de muestra:

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

Puede tomar su entrada y salida en cualquier formato razonable, como STDIN / STDOUT, argumentos de función y valor de retorno, lectura y escritura de archivos, etc. Se aplican lagunas estándar. ¡La respuesta más corta en bytes gana!


¹ Esto es pasivo-agresivo y una idea terrible. ¿Te ha no consigue esta idea de mí.

DJMcMayhem
fuente
8
Mis disculpas a Jimmy
DJMcMayhem
66
Relacionado.
DLosc
@DLosc ¡Ah, eso es lo que Jimmy está usando en su secuencia de comandos previa a la confirmación!
Bergi
99
Por supuesto que Jimmy no es un jugador de código.
jimmy23013
Este desafío realmente susurró a mis Jimmies .
DanTheMan

Respuestas:

8

Empuje, 43 36 bytes

No es necesario que le des un guión a Jimmy, solo enséñale a usar un editor de texto adecuado. (retornos literales para mayor claridad)

:%s/.*=//|%s/;\n/,/<cr><cr>
3wcf ] = {<esc>
$s};
m-chrzan
fuente
¡Agradable! En este caso específico, <C-a>es más corto que t], lo cual es un pequeño truco divertido. Además, creo que técnicamente necesita 2, <cr>ya que pide confirmación.
DJMcMayhem
Las respuestas de Vim a los desafíos estándar de código de golf deben puntuarse en bytes.
Martin Ender
Además, norm df=es más corto ques/.*=//g
DJMcMayhem
1
Además, 3wC] = {<esc>es más corto que <C-a>di]$s = {<esc>.
DJMcMayhem
1
@Geobits ¿Dónde está tu respuesta de Emacs?
Neil
7

CJam, 43 36 bytes

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

Ejemplo en línea

Explicación:

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

Muchas gracias a Martin Ender por las mejoras en mi primera respuesta de CJam.

Linus
fuente
6

JavaScript (ES6), 65 64 63 bytes

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

Retina , 30 28 bytes

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

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

Pruébalo en línea!

Explicación

Utilizaremos la siguiente entrada como ejemplo:

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

Nivel 1

\d+];¶.+ 
] = {

Tenga en cuenta que hay un espacio final en la primera línea.

Comenzamos haciendo coincidir un número que sigue ];y un salto de línea, y luego todo hasta el último espacio en la siguiente línea. Esta coincidencia solo se puede encontrar al final de la primera línea (debido a ];). Todo esto se reemplaza con ] = {. Es decir, transforma nuestra entrada de ejemplo a:

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

Etapa 2

;¶.+=
,

Ahora combinamos todo, desde a ;hasta =en la línea siguiente, y reemplazamos con a ,. Esto transforma la cadena a:

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

Etapa 3

;
};

Todo lo que queda es arreglar el final y lo hacemos reemplazando el único restante ;con };:

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

Julia, 112 108 105 Bytes

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

Explicación

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 guardados reemplazando collect (eachmatch ()) con [eachmatch () ...] y con una expresión regular más corta

nyro_0
fuente
Hola, bienvenido a PPCG! Esto parece una gran primera respuesta. +1 de mi parte Dado que el desafío dice " Puede tomar su entrada y salida en cualquier formato razonable ", puede eliminar el espacio después del separador de coma en la eachmatchllamada de función para una salida menos bonita y -1 byte. Yo mismo nunca programé en Julia, pero puede que le resulte interesante leer esta publicación: Consejos para jugar al golf en Julia . Nuevamente bienvenido, y disfrute su estadía. :)
Kevin Cruijssen
1
muchas gracias por sus amables palabras :) PPCG parecía ser divertido de investigar, así que pensé en probarlo. Elija a Julia por esta respuesta ya que aún no estaba presente
nyro_0
El uso matchallprobablemente sería más corto que las salpicaduras eachmatch.
Alex A.
Intenté usar matchall primero, pero no me permite usar grupos de expresiones regulares (la parte en el paréntesis en lo que estoy particularmente interesado) en lugar de cada coincidencia. (¿o simplemente no pude encontrarlo en la documentación?)
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
Un taco
fuente
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: La línea set s=,termina con un espacio. Toma entrada en STDIN. Esa línea extraña 3 toma la entrada (por ejemplo, int spam[6];y cambia el [en [] = {&remlo que resulta en set s=int spam[] = {&rem 6];que luego se interpreta como dos declaraciones, set s=int spam[] = {y rem 6];, el último de los cuales es un comentario. Luego, para cada línea de borramos el texto hasta el primer espacio (porque se puede No utilice =en un patrón y la coincidencia no es codicioso) y extraiga el valor.

Neil
fuente
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
fuente
3

Python 112 111

Muy sencillo para mí, sugiera cualquier mejora que se me ocurra.

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
fuente
A simple vista, puedo ver que hay un espacio en blanco inútil [:-1] for.
Yytsi
2

05AB1E , 31 30 28 bytes

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

Explicación

ž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

Pruébalo en línea!

Salvó un byte gracias a Adnan

Emigna
fuente
žuDÀÀen lugar de „[]„{}guardar un byte :).
Adnan
@Adnan: Correcto, buena 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("..$","};");}

Múltiples bytes guardados gracias a @cliffroot .

Ungolfed y código de prueba:

Pruébalo aquí

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

Salida:

spam eggs[] = {0, 4, 8, -3, 3, 7, 888, 555, 0, -2};
char ans[] = {52, 50};
blah_blah quux[] = {105};
Kevin Cruijssen
fuente
1
pocos bytes guardadosString 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
@cliffroot ¡Gracias! De hecho, algunos trucos agradables como reutilizar el Stringen el parámetro y reemplazar el último carácter con en "};");lugar de un "")+"};";.
Kevin Cruijssen
2

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

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

Necesidades -py -0banderas para correr. Por ejemplo :

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

Jalea , 27 bytes

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

Pruébalo en línea!

Explicación

Ỵ         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
fuente
1

sed 51

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

Java, 106 bytes

La manipulación de cadenas en Java es un infierno, como siempre.

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

Esta es una respuesta pura regex. Haga un solo concatenado String, luego realice replaceXxxhasta que esté bien.

Pruebas y sin golf:

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
fuente
0

Jalea , 33 bytes

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

TryItOnline

¿Cómo?

ỴḊḲ€Ṫ€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
fuente
Abajo votante, ¿qué tiene de malo?
Jonathan Allan
0

JavaScript, 125 bytes

Sé que es más largo que otros, pero realmente quería usarlo eval. Solo por diversión.

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 ejecutar, pegue lo siguiente aquí :

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

Los nombres de funciones largos mataron esto: D

¡Prueba las maletas aquí !

Yytsi
fuente
0

V , 25 , 24 bytes

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

Pruébalo en línea! Este contiene un <esc>carácter no imprimible , así que aquí hay un hexdump:

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

Explicación:

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
fuente