Développer un tableau C


36

Dans le langage de programmation C, les tableaux sont définis comme suit:

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

La taille du tableau est déduite des éléments d'initialisation, qui dans ce cas sont 6. Vous pouvez également écrire un tableau C de cette façon, en le dimensionnant explicitement, puis en définissant chaque élément dans l'ordre:

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;

Le défi

Vous devez écrire un programme ou une fonction qui étend les tableaux de la première à la seconde. Puisque vous écrivez un programme pour rendre le code plus long et que vous aimez l'ironie, vous devez rendre votre code le plus court possible.

L'entrée sera une chaîne représentant le tableau d'origine et la sortie sera la définition de tableau développée. Vous pouvez sans risque supposer que l'entrée ressemblera toujours à ceci:

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

"Type" et "array_name" seront entièrement composés de caractères alphabétiques et de soulignés _. Les éléments de la liste seront toujours un nombre compris entre -2 147 483 648 et 2 147 483 647. Les entrées dans un autre format ne doivent pas être gérées.

Les espaces de votre sortie doivent correspondre exactement à ceux de la sortie de test, même si une nouvelle ligne est autorisée.

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

Les soumissions dans toutes les langues sont encouragées, mais des points bonus si vous pouvez le faire en C.

Classement:

Voici un tableau montrant les principales réponses:


2
Les espaces entre l'index du tableau, le signe égal et les valeurs requises dans la sortie? Par exemple, serait foo[0]=1;acceptable?
Mego

@ Mego Cela ne serait pas acceptable. Les espaces sont nécessaires. Je vais éditer ça.
DJMcMayhem

Le retour à la ligne est-il autorisé?
Luis Mendo

Les fonctions sont-elles autorisées?
Mego

Est-il possible de renvoyer la sortie au lieu de l'imprimer? (en cas de fonctions)
vaultah

Réponses:


12

Pyth, 44 octets

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

Suite de tests

Expression régulière et coupe de chaîne. Pas particulièrement intelligent.

Explication:

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

Cette réponse est l'épine dans mon côté. Je pensais pouvoir gagner avec vim, mais pour ma vie, je ne peux pas obtenir les 2 ou 3 derniers octets. = D Bonne réponse!
DJMcMayhem

28

Vim, 54, 52, 49 47 frappes


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

Explication:

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

Maintenant, notre tampon ressemble à ceci:

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

et notre curseur est sur la dernière ligne.

Deuxième partie:

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

Maintenant, tout semble aller bien, il suffit d'ajouter la déclaration de tableau d'origine. Donc nous faisons:

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
Chaque fois que je lis un vim-golf, je me rends compte que tout le codage que je fais (principalement les commandes au clavier de mes divers éditeurs d'interface graphique) ressemble beaucoup à ceci et que mon esprit se penche un peu (Vim est juste complet (et plus froid)) : P
chat

Je ne parviens pas à faire fonctionner cela. Lorsque je tape le premier "@q" (sur "@ qq @ q"), la macro s'exécute ensuite, et semble aller plus loin qu'il ne le devrait, en obtenant des éléments tels que int foo[6] = {et se terminant par int foo[12(curseur sur le "2")
LordAro

@ LordAro, j'aurais probablement dû le mentionner. Cela est dû au fait qu’il existe déjà une macro dans q et qu’elle s’exécute pendant l’enregistrement. J'ai expliqué comment contourner ce problème
DJMcMayhem

1
@ LordAro Oh, duh, je sais ce qui cause ça. J'ai changé df<space>pour dWenregistrer un octet, mais j'ai oublié que df<space>cela sortirait de la macro à la ligne 6, mais ce dWn'est pas le cas. Je reviens sur une révision. Merci d'avoir fait remarquer cela!
DJMcMayhem

1
Bien que ce ne soit pas la réponse la plus courte, c'est de loin la plus impressionnante.
isaacg

10

Retina, 108 104 100 69 octets

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

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

Battez ça, PowerShell ...

Explication du code

Première ligne: ].+{((\S+ ?)+)

Premièrement, nous devons conserver le type, le nom du tableau et le crochet d’ouverture (cela enregistre un octet), afin de ne pas les faire correspondre. Nous avons donc correspondre le support de fermeture, un certain nombre de caractères, et une accolade d' ouverture: ].+{. Ensuite, nous correspondons à la liste de numéros. Shortest Je suis en mesure de trouver est jusqu'à présent ceci: ((\S+ ?)+). Nous faisons correspondre un nombre de caractères non-espace (ce qui inclut les chiffres, signe négatif possible, et par des virgules possible), suivi d'un espace, qui peut ou ne peut pas être là: \S+ ?. Ce groupe de caractères est ensuite répété autant de fois que nécessaire: (\S+ ?)+et placé dans le grand groupe de capture. Notez que nous ne correspondons pas à l'accolade ou au point-virgule de fermeture. La troisième ligne explique pourquoi.

Deuxième ligne: $#2];$1

Comme nous n'avons associé qu'une partie de l'entrée, les parties non appariées seront toujours là. Nous avons donc la longueur de la liste après le support d'ouverture inégalée: $#2. Le modificateur de remplacement #nous aide dans cette tâche , car il nous donne le nombre de correspondances créées par un groupe de capture donné. Dans ce cas, groupe de capture 2. Ensuite, nous mettons un crochet de fermeture et un point-virgule, et enfin toute notre liste.

Avec entrée short array[] = {4, 3, 2, 1};, la représentation interne après ce remplacement est la suivante:

réseau court [4]; 4, 3, 2, 1};

(notez l'accolade et le point-virgule fermants)

Troisième ligne: +`((\w+[).+;(\S+ )*)(-?\d+).+

Ceci est une section en boucle. Cela signifie qu'il fonctionne jusqu'à ce qu'aucune étape de la boucle ne modifie l'entrée. Tout d' abord nous faisons correspondre le nom du tableau, suivi d'un support d'ouverture: (\w+\[). Ensuite , un nombre arbitraire de tous les caractères et un point - virgule: .+;. Ensuite , nous avons à nouveau correspondre à la liste, mais cette fois que le nombre et la virgule après chaque numéro, qui ont un espace qui suit: (\S+ )*. Ensuite , nous saisissons le dernier numéro dans la liste: (-?\d+)et tous les caractères restants derrière elle: .+.

Quatrième ligne: $1¶$2$#3] = $4;

Nous remplaçons ensuite avec le nom du tableau et la liste suivie d'une nouvelle ligne: $1¶. Ensuite, nous avons mis le nom du tableau, suivi de la longueur de la liste en correspondance précédemment, sans le dernier élément (essentiellement list.length - 1): $2$#3. Suivi d'un crochet de fermeture et d'un opérateur d'assignation avec des espaces, suivi du dernier élément de notre liste de numéros:] = $4;

Après le remplacement, la représentation interne ressemble à ceci:

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

Notez que l'accolade fermante et le point-virgule ont disparu, grâce .+à la fin de la troisième ligne. Après trois remplacements supplémentaires, la représentation interne ressemble à ceci:

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

Puisqu'il n'y a plus rien à faire par la troisième ligne, la quatrième ne remplace rien et la chaîne est renvoyée.

TL; DR: Commençons par modifier légèrement le format de la liste int. Ensuite, nous prenons le dernier élément de la liste et le nom, et les plaçons après l'initialisation du tableau. Nous faisons cela jusqu'à ce que la liste int soit vide. Ensuite, nous rendons le code modifié.

Essayez-le en ligne!


Quelqu'un m'a battu à elle .... :(
CalculatorFeline

M!`et G`sont similaires, mais pas tout à fait les mêmes. Faites attention.
CalculatriceFeline

L'explication de troisième ligne m'embrouille. Le premier élément est le seul sans espace derrière, pas le dernier.
CalculatriceFeline

@CatsAreFluffy J'ai essayé de modifier un peu la formulation tout à l'heure. Ce que je voulais dire était un espace suivant un nombre, pas le précédant. Je suppose que je n'ai pas pleinement compris la signification de "derrière". Je ne devrais vraiment pas écrire d'explications de code à 2 heures du matin.
daavko

@daavko "Behind" signifie normalement "après", c'est-à-dire "suivant", en anglais courant. Vous étiez bien.
Le procès de Monica

9

V, 37 octets

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

V est un langage de golf 2D basé sur des cordes que j'ai écrit, conçu à partir de vim. Cela fonctionne à partir de commit 17 .

Explication:

C'est à peu près une traduction directe de ma réponse vim , bien que nettement plus courte.

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

Ensuite, nous avons juste:

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

Comme il peut être difficile d'entrer dans cette folie unicode, vous pouvez créer le fichier avec cet hexdump réversible:

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.

Cela peut être exécuté en installant V et en tapant:

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

1
Designed off of vim.2 notes: 1. la plupart des gens disent fromnon off of, et 2. pourquoi cela n'existait-il pas. +1
Rɪᴋᴇʀ

8

C, 215 octets , 196 octets

19 octets sauvés grâce à @tucuxi!

Golfé:

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

Lien:

http://ideone.com/h81XbI

Explication:

Pour obtenir le <type> <array_name>, la sscanf()chaîne de format est la suivante:

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

Pour extraire les valeurs int de la chaîne int foo[] = {4, 8, 15, 16, 23, 42};, je tokenize essentiellement la chaîne avec cette fonction:

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

où:

  • iest la chaîne d'entrée (a char*)
  • t est le décalage de l'emplacement du pointeur de i
  • xest la intlecture réelle de la chaîne
  • n est le nombre total de caractères consommés, y compris le chiffre trouvé

La sscanf()chaîne de format signifie ceci:

%*            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 vous visualisez la chaîne d'entrée sous la forme d'un tableau de caractères:

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

avec l' int 4être situé à l'index 13, 8à l'index 16, etc., voici à quoi ressemble le résultat de chaque exécution dans la boucle:

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
vous pouvez éviter d'utiliser strcat en concaténant à l' ointérieur de sprintf, via %s. Cela devrait raser environ 7 caractères.
Tucuxi

@tucuxi Ah, bonne prise. Merci!
homersimpson

7

C, 195 180 octets

195 octets d'origine:

joué au golf:

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
}

Les deux raccourcis utilisent le mmodificateur to pour permettre à scanf %sd'allouer sa propre mémoire (enregistre les tableaux de caractères), et utilisent strtok(qui est également disponible par défaut, sans includes) le composant d'analyse syntaxique.


Mise à jour de 180 octets:

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

Utilise l’ idée de bnf679 d’ajouter à une chaîne pour éviter de compter les virgules.


6

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

Fait un usage intensif de f-strings .

Version non-golfée:

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
Woah, j'ai oublié à propos de f-strings. Ceux qui vont être super utiles pour le golf!
Morgan Thrapp

Je pense que vous pouvez sauvegarder un octet en utilisant une liste de compréhension au lieu de la boucle normale
somewithpc

@ someonewithpc: Nope, il faudrait en fait ajouter 1 octet supplémentaire
vaultah

5

Ruby, 127 110 108 99 88 octets

Fonction anonyme avec un seul argument en entrée. Programme complet, lit l'entrée de STDIN. (Si vous dirigez un fichier vers l'intérieur, la nouvelle ligne de fin est facultative.) Valeurs renvoyées Imprime la chaîne de sortie.

@TimmyD s'est vanté de voir sa solution vaincre tous les autres non-esolangs comme un défi, et a finalement vaincu la solution Powershell de 114 octets (au moment de la rédaction de cet article). Le truc de Cʀɪᴇɴ O'Bʀɪᴇɴ qui consiste à scinder ]et à épisser la seconde moitié pour obtenir les chiffres.

J'ai besoin d'utiliser davantage l'opérateur Splat. C'est tellement utile!

@ Neil's JavaScript ES6 a emprunté une astuce pour économiser davantage d'octets en recherchant des mots plutôt gsubqu'en utilisant et split..

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

AFAICT la tâche est d'écrire un programme complet.
vaultah

@vaultah Le code par défaut pour le golf de golf est un programme ou une fonction
Mego

@Mego: l'OP a dit "Vous devez écrire un programme"
vaultah

@ vaultah normalement je dirais que le code golf me permet d'utiliser une fonction, mais un programme complet m'a sauvé 2 octets, alors pourquoi pas?
Value Ink

Ooof ... Je ne pense pas que PowerShell puisse en arriver à cela. Avoir un +1
AdmBorkBork

4

05AB1E , 52 50 47 octets

Code:

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

Utilise le codage CP-1252 . Essayez-le en ligne! .


1
C'est arrivé au point où je saute toutes les autres réponses simplement en recherchant vos réponses 05AB1E. La langue me fascine absolument.
WorseDoughnut

1
@WorseDoughnut Merci! C'est la chose la plus gentille que quelqu'un m'ait jamais dite à propos de 05AB1E :)!
Adnan

4

JavaScript (ES6), 100 octets

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

Etant donné que seuls les mots sont importants, cela fonctionne en faisant simplement correspondre tous les mots de la chaîne d'origine, plus les signes moins, puis en générant le résultat. (Au départ, je pensais que j'allais utiliser, replacemais cela s'est avéré être un piège rouge.)


[t,n,...m]presque une vision mystique
edc65

4

Pyth - 53 50 46 45 44 octets

2 octets enregistrés grâce à @FryAmTheEggman.

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

Suite de test .


4

Pip , 48 47 octets

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

Prend une entrée de stdin et imprime sur stdout.

Explication

Tl; dr: Effectue un remplacement de regex en utilisant des groupes de capture et une fonction de rappel pour construire le résultat.

La qvariable spéciale lit une ligne d'entrée. La regex est (\S+)(. = ).(.+)}, qui correspond à tout sauf au type (y compris l'espace de fin) et au point-virgule final. En utilisant le premier exemple de la question, les groupes de capture se foo[, ] = et 4, 8, 15, 16, 23, 42.

Le remplacement est la valeur de retour de la fonction non nommée {[b#Yd^k']';.n.b.,#y.c.y]}, qui est appelée avec la correspondance complète plus les groupes de capture en tant qu'arguments. Ainsi, dans la fonction, bobtient le groupe de capture 1, cobtient le groupe 2 et dobtient le groupe 3.

Nous construisons une liste, les trois premiers points qui seront "foo[", 6et "]". Pour obtenir le 6, nous séparons la dvariable intégrée k= ", ", Yajoutons la liste résultante d'entiers dans la yvariable pour une utilisation ultérieure et prenons la longueur ( #). ']est un caractère littéral.

Ce qu'il reste à faire, c'est de construire une série de chaînes de la forme ";\nfoo[i] = x". Pour ce faire, nous concaténons ce qui suit: ';, n(intégré pour newline), b(1er groupe de capture), ,#y(équivalent à Python range(len(y))), c(2e groupe de capture), et y. La concaténation fonctionne élément par élément sur les listes et les plages. Le résultat est donc une liste de chaînes. En mettant tout cela ensemble, la valeur de retour de la fonction sera une liste comme celle-ci:

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

Puisque cette liste est utilisée dans un Rremplacement de chaîne , elle est implicitement convertie en chaîne. La conversion par défaut de liste à chaîne dans Pip concatène tous les éléments:

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

Enfin, le résultat (y compris le type et le point-virgule final, qui ne correspondait pas à la regex et reste donc inchangé) est automatiquement imprimé.


4

Perl 5.10, 73 72 68 66 + 1 (pour le commutateur -n) = 67 octets

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

C'est un beau défi pour Perl et le plus court parmi les langages à usage général à ce jour. Équivalent à

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

4

PowerShell v2 +, 114 à 105 octets

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

Prend la chaîne d'entrée $argset -replaces le crochet sans rien, puis effectue un -splitespace blanc. Nous stockons le premier bit dans $a, le second bit dans $b, les éléments =into $cet array dans $d. Pour l'exemple ci-dessous, cela stocke foodans $aet bardans $b, et tout le tableau dans$d .

Nous avons ensuite la sortie de notre première ligne avec "$a ..."et au milieu transformons $dd'un tableau de chaînes de forme {1,, 2,... 100};à un réseau régulier int en -joining ensemble en une seule chaîne, puis en cours d' exécution par iexdeux fois (semblable à eval). Nous stockons ce tableau résultant $davant d'appeler la .lengthméthode pour renseigner le nombre approprié entre la []ligne de sortie.

Nous envoyons ensuite $dune boucle avec |%{...}. Chaque itération que nous produisons "$b..."avec une variable de compteur $iencapsulée entre parenthèses et la valeur actuelle $_. La $ivariable de commence initialisés (équivalent à $null) mais ++sera jeté à un intavant la sortie, il commencera à la sortie 0, tout avant d' incrémenter $ipour la prochaine itération de la boucle.

Toutes les lignes de sortie sont laissées sur le pipeline et la sortie vers le terminal est implicite à la fin du programme.

Exemple

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;

Ouf! J'ai réussi à faire passer ma réponse Ruby au-dessus de la tienne en prenant ton commentaire sur le fait de battre les autres non-esolangs comme un défi! Bon travail, cependant, +1.
Value Ink

@ KevinLau Merci! De retour chez toi avec un 105 maintenant. ;-)
AdmBorkBork

Je vais appeler votre 105 et vous élever un 99! : D
Value Ink

Pas plus près de battre Retina.
CalculatriceFeline

3

C, 278 280 octets

joué au golf:

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

Pendant que nous travaillions là-dessus, certaines personnes ont publié une version abrégée utilisant sscanf pour l’analyse plutôt que des pointeurs de données ... bien sympa!

UPDATE: Des espaces manquants repérés autour des égaux dans l'impression d'élément, lien en ligne IDE: http://ideone.com/KrgRt0 . Notez que cette implémentation supporte les nombres négatifs ...


2

Awk, 101 octets

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

Plus lisiblement:

{
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
}
  • Je règle le séparateur de champ sur tout sauf les alphabets, les chiffres, le trait de soulignement et -. Ainsi, les champs seraient le nom du type, le nom de la variable et les nombres.
  • Le nombre de champs sera 1 (pour le type) + 1 (pour le nom) + N (nombres) + 1 (un champ vide après la fin };). Donc, la taille du tableau est NF - 3.
  • Ensuite, il s’agit simplement d’imprimer une ligne spéciale pour la déclaration et d’enrouler les chiffres.
  • Je devrais assigner FSsoit en invoquant awk (using -F), soit en BEGINbloc. Par souci de brièveté,…

1
En fait, il FSdoit être assigné soit en soit en BEGINutilisant -Fsinon il ne sera pas utilisé pour scinder la première ligne, et comme il n'y a qu'une ligne d'entrée ...
Robert Benson

@ RobertBenson vous avez raison, la commande serait donc 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}'102 octets sans compter awkelle-même. Hmmm. Est-ce que je peux exclure les citations?
muru

Oui, vous pouvez exclure les devis. Vous le listez parfois comme C+O bytesCet Oreprésentez les octets du code et des options, respectivement. Bien sûr, je n'utilise généralement qu'un BEGINbloc, donc je n'ai pas à y penser. : p
Robert Benson

2

JavaScript ES6, 134 132 130 129 octets

Sauvé 1 octet grâce à 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`
`)

Ne devrait pas `[${i}] = `+t+";"être `[${i}] = ${t};`?
Neil

@ Neil Merci, enregistré un octet!
Conor O'Brien

2

bash, 133 129 octets

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

Première tentative, bien sûr, il est possible de la raccourcir.


2

RÉ, 197 , 188 octets

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 non-golfés:

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

Je ne sais pas D, mais pourriez-vous lire le crochet d'ouverture dans le nom? Cela vous éviterait d'avoir à écrire un crochet séparément plus tard.
DLosc

2

Julia, 154 134 101 octets

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

Il s'agit d'une fonction qui accepte une chaîne et retourne une chaîne avec une nouvelle ligne de fin.

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

Nous définissons cêtre un tableau de correspondances de l'entrée sur l'expression régulière -?\w+. Il indique le type, le nom du tableau, puis chaque valeur. Nous stockons ncomme la longueur dec - 2, qui est le nombre de valeurs. La sortie est construite sous la forme d'une chaîne de type, de nom et de longueur interpolée, combinée à chaque ligne de définition séparée par des nouvelles lignes. Pour quelque raison que ce soit, c[]est le même quec[1] .

Enregistré 32 octets avec l'aide de Dennis!


1

Python 2, 159 octets

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

Essayez-le en ligne

Merci Kevin Lau pour certaines suggestions de golf


1

Python 3, 116 octets

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

Divise l'entrée en type, nom et liste de nombres. Après avoir imprimé la matrice en déclarant, imprime les éléments en énumérant manuellement les nombres, en supprimant les excès de ponctuation attachés aux premier et dernier.

Une approche différente dans Python 2 est sortie à 122 octets:

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

L'idée est de faire en evalsorte que la liste de nombres soit un tuple, avec une virgule à la fin, de sorte qu'un seul numéro soit reconnu en tant que type. La liste énumérée de nombres fournit des nuplets au format chaîne dans.


1

PHP, 143 octets

Golfé

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

L'entrée est prise via un argument de ligne de commande. Échantillon:

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

Sortie:

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 octets

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

Ce n'est pas C, mais il utilise la sprintffonction Nah, qui gaspillait 4 octets.

Essayez-le en ligne!

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

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

Je ne pouvais pas bien fusionner awful_array_name[5];et awful_array_name[0] = 7;parties pour pouvoir réutiliser du code: /

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.