Jimmy ces tableaux vers le bas


23

Mon collègue, Jimmy est un peu nouveau pour C / C ++. Il est également un peu lent à apprendre. Maintenant, pour être juste, son code compile toujours, mais il a des habitudes très bâclées. Par exemple, tout le monde sait que vous pouvez définir un tableau comme celui-ci:

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

Tout le monde, sauf Jimmy. Il est convaincu que la seule façon de créer un tableau est la suivante:

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

Je continue de résoudre ce problème pour lui dans la révision de code, mais il n'apprendra pas. J'ai donc besoin que vous écriviez un outil qui le fasse automatiquement pour lui lorsqu'il s'engage¹.

Le défi

Je veux que vous écriviez un programme complet ou une fonction qui accepte une chaîne multiligne en entrée et génère la version plus compacte du tableau C. L'entrée suivra toujours ce format, espaces inclus:

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 bref, l'entrée sera toujours valide et bien définie C. Plus en détail:

Tous les identifiants seront constitués uniquement de lettres et de traits de soulignement. La longueur sera toujours d'au moins un, et il n'y aura jamais d'index manquant ou hors limites. Vous pouvez également supposer que les index sont en ordre. Par exemple:

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

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

et

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

sont toutes des entrées non valides et peuvent provoquer un comportement indéfini dans votre soumission. Vous pouvez également supposer que tous les nombres seront des nombres décimaux valides, négatifs ou positifs. L'entrée n'aura pas d'espaces superflus. La sortie doit toujours suivre ce format, les espaces inclus:

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

Voici quelques exemples de données:

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

Vous pouvez prendre vos entrées et sorties dans n'importe quel format raisonnable, tel que STDIN / STDOUT, les arguments de fonction et la valeur de retour, la lecture et l'écriture de fichiers, etc. Des échappatoires standard s'appliquent. La réponse la plus courte en octets gagne!


¹Ceci est passif-agressif et une idée terrible. Vous ne m'avez pas donné cette idée.


8
Mes excuses à Jimmy
DJMcMayhem


@DLosc Ah, c'est ce que Jimmy utilise dans son script de pré-validation!
Bergi

9
Bien sûr, Jimmy n'est pas un golfeur de code.
jimmy23013

Ce défi a vraiment brouillé mes Jimmies .
DanTheMan

Réponses:


8

Vim, 43 36 octets

Vous n'avez pas besoin de donner à Jimmy un script, apprenez-lui simplement à utiliser un éditeur de texte approprié. (retours littéraux pour plus de clarté)

:%s/.*=//|%s/;\n/,/<cr><cr>
3wcf ] = {<esc>
$s};

Agréable! Dans ce cas précis, <C-a>est plus court que t], ce qui est un petit hack amusant. De plus, je pense que vous avez techniquement besoin de 2, <cr>car il demande une confirmation.
DJMcMayhem

Les réponses Vim aux défis de code-golf standard doivent être notées en octets.
Martin Ender

Aussi, norm df=est plus court ques/.*=//g
DJMcMayhem

1
En outre, 3wC] = {<esc>est plus court que <C-a>di]$s = {<esc>.
DJMcMayhem

1
@Geobits Où est votre réponse Emacs?
Neil

7

CJam, 43 36 octets

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

Exemple en ligne

Explication:

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

Un grand merci à Martin Ender pour les améliorations apportées à ma première réponse CJam.


6

JavaScript (ES6), 65 64 63 octets

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

5

Rétine , 30 28 octets

Le nombre d'octets suppose un codage ISO 8859-1.

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

Essayez-le en ligne!

Explication

Nous utiliserons l'entrée suivante comme exemple:

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

Étape 1

\d+];¶.+ 
] = {

Notez qu'il y a un espace de fin sur la première ligne.

Nous commençons par faire correspondre un nombre suivant par ];et un saut de ligne, puis tout jusqu'au dernier espace sur la ligne suivante. Cette correspondance ne peut être trouvée qu'à la fin de la première ligne (en raison de ];). Tout cela est remplacé par ] = {. Autrement dit, il transforme notre exemple d'entrée en:

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

Étape 2

;¶.+=
,

Maintenant, nous faisons correspondre tout de a ;à la =ligne suivante et nous remplaçons par a ,. Cela transforme la chaîne en:

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

Étape 3

;
};

Il ne reste plus qu'à fixer la fin et nous le faisons en remplaçant le seul restant ;par };:

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

5

Julia, 112 108 105 Octets

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

Explication

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(

Octets enregistrés en remplaçant collect (eachmatch ()) par [eachmatch () ...] et par une expression rationnelle plus courte


Salut, bienvenue chez PPCG! Cela ressemble à une excellente première réponse. +1 de moi. Étant donné que le défi indique " Vous pouvez prendre vos entrées et sorties dans n'importe quel format raisonnable ", vous pouvez supprimer l'espace après le séparateur de virgules dans l' eachmatchappel de fonction pour une sortie moins jolie et -1 octet. Je n'ai jamais programmé de Julia moi-même, mais vous pourriez trouver ce post intéressant à lire: Conseils pour jouer au golf à Julia . Encore une fois bienvenue et profitez de votre séjour. :)
Kevin Cruijssen

1
merci beaucoup pour vos aimables paroles :) PPCG semblait être amusant à regarder, donc j'ai pensé que je vais essayer. Choisissez Julia pour cette réponse car elle n'était pas encore présente
nyro_0

L'utilisation matchallserait probablement plus courte que les éclaboussures eachmatch.
Alex A.

J'ai d'abord essayé d'utiliser matchall, mais cela ne me permet pas d'utiliser des groupes d'expression régulière (la partie entre parenthèses qui m'intéresse particulièrement) par opposition à chaque match. (ou je ne le trouvais tout simplement pas dans la documentation?)
nyro_0

3

Lua, 121 octets.

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

Expliqué

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

3

Lot, 160 octets

@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

Remarque: la ligne set s=,se termine par un espace. Prend entrée sur STDIN. Cette ligne bizarre 3 prend l'entrée (par exemple , int spam[6];et modifie la [en [] = {&rementraînant set s=int spam[] = {&rem 6];qui obtient ensuite interprété comme deux déclarations, set s=int spam[] = {et rem 6];, dont le dernier est un commentaire. Ensuite , pour chaque ligne , nous supprimons le texte jusqu'au premier espace (parce que vous pouvez ne pas utiliser =dans un modèle et la correspondance n'est pas gourmande) et extraire la valeur.


3

C, 121 octets

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

3

Python 112 111

Très simple pour moi, veuillez suggérer toute amélioration qui vous vient à l'esprit.

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

En un coup d'œil, je peux voir qu'il y a un espace blanc inutile [:-1] for.
Yytsi

2

05AB1E , 31 30 28 octets

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

Explication

ž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

Essayez-le en ligne!

Un octet enregistré grâce à Adnan


žuDÀÀau lieu d' „[]„{}enregistrer un octet :).
Adnan

@Adnan: Bon, bonne prise!
Emigna

2

Java 7, 159 158 149 154 octets

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

Plusieurs octets enregistrés grâce à @cliffroot .

Code non testé et testé:

Essayez-le ici.

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

Sortie:

spam eggs[] = {0, 4, 8, -3, 3, 7, 888, 555, 0, -2};
char ans[] = {52, 50};
blah_blah quux[] = {105};

1
quelques octets enregistrésString 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 Merci! En effet, de belles astuces comme réutiliser le Stringdans le paramètre et remplacer le dernier caractère par "};");au lieu d'un "")+"};";.
Kevin Cruijssen

2

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

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

Besoins -pet -0indicateurs pour fonctionner. Par exemple :

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

1

Gelée , 27 octets

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

Essayez-le en ligne!

Explication

Ỵ         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 “};”

1

sed 51

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

1

Java, 106 octets

La manipulation des chaînes en Java est un enfer, comme toujours.

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

Ceci est une pure réponse regex. Faites un single concaténé String, puis jouez replaceXxxjusqu'à ce que ce soit ok.

Test et non 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);
  }
}

0

Gelée , 33 octets

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

TryItOnline

Comment?

ỴḊḲ€Ṫ€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 '=')

Votant - qu'est-ce qui ne va pas?
Jonathan Allan


0

JavaScript, 125 octets

Je sais que c'est plus long que les autres, mais je voulais vraiment l'utiliser eval. Juste pour le fun.

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

Pour exécuter, collez ce qui suit ici :

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)

0

Haxe, 234 octets

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

Les noms de fonction longs ont tué ceci: D

Essayez les testcases ici !


0

V , 25 , 24 octets

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

Essayez-le en ligne! Celui-ci contient un <esc>caractère non imprimable , voici donc un vidage hexadécimal:

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

Explication:

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:
                          };    "'};'
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.