Erweitern Sie ein C-Array


36

In der Programmiersprache C sind Arrays wie folgt definiert:

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

Die Größe des Arrays ergibt sich aus den initialisierenden Elementen (in diesem Fall 6). Sie können auch ein C-Array auf diese Weise schreiben, seine Größe explizit festlegen und dann jedes Element in der folgenden Reihenfolge definieren:

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;

Die Herausforderung

Sie müssen ein Programm oder eine Funktion schreiben, die Arrays von der ersten zur zweiten Möglichkeit erweitert. Da Sie ein Programm schreiben, um Code länger zu machen, und Ironie lieben, müssen Sie Ihren Code so kurz wie möglich halten.

Die Eingabe ist eine Zeichenfolge, die das ursprüngliche Array darstellt, und die Ausgabe ist die erweiterte Array-Definition. Sie können davon ausgehen, dass die Eingabe immer so aussieht:

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

"Type" und "array_name" bestehen ausschließlich aus Buchstaben und Unterstrichen _. Die Elemente der Liste sind immer eine Zahl im Bereich von -2.147.483.648 bis 2.147.483.647. Eingaben in einem anderen Format müssen nicht verarbeitet werden.

Das Leerzeichen in Ihrer Ausgabe muss genau mit dem Leerzeichen in der Testausgabe übereinstimmen, auch wenn ein abschließender Zeilenumbruch zulässig ist.

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;

Einsendungen in jeder Sprache werden empfohlen, aber Bonuspunkte, wenn Sie dies in C tun können .

Bestenliste:

Hier ist eine Rangliste mit den wichtigsten Antworten:


2
Sind die Leerzeichen zwischen dem Array-Index, dem Gleichheitszeichen und den Werten in der Ausgabe erforderlich? Wäre zum Beispiel foo[0]=1;akzeptabel?
Mego

@Mego Das wäre nicht akzeptabel. Das Leerzeichen ist erforderlich. Ich bearbeite das in.
DJMcMayhem

Zeilenumbruch erlaubt?
Luis Mendo

Sind Funktionen erlaubt?
Mego

Ist es in Ordnung, die Ausgabe zurückzugeben, anstatt sie zu drucken? (im Falle von Funktionen)
Gewölbe

Antworten:


12

Pyth, 44 Bytes

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

Testsuite

Regulärer Ausdruck und String-Chopping. Nicht besonders schlau.

Erläuterung:

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

Diese Antwort ist der Dorn in meiner Seite. Ich dachte, ich könnte es in vim gewinnen, aber für mein ganzes Leben kann ich die letzten 2-3 Bytes nicht rausholen. = D Schöne Antwort!
DJMcMayhem

28

Vim, 54, 52, 49, 47 Tastenanschläge


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

Erläuterung:

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

Jetzt sieht unser Puffer so aus:

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

und unser Cursor befindet sich in der letzten Zeile.

Zweite Hälfte:

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

Jetzt sieht alles gut aus, wir müssen nur noch die ursprüngliche Array-Deklaration hinzufügen. So machen wir es:

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
Jedes Mal, wenn ich einen Vim-Golf lese, merke ich, dass die gesamte Codierung, die ich mache (hauptsächlich Tastaturbefehle in meinen verschiedenen GUI-Editoren), ungefähr so ​​aussieht. : P
Katze

Ich kann das nicht zum Laufen bringen - wenn ich das erste "@q" (von "@ qq @ q") eingebe, wird das Makro ausgeführt und anscheinend läuft es weiter als es sollte. Dinge wie int foo[6] = {und endend mit int foo[12(Cursor an) die "2")
LordAro

@ LordAro Ich hätte das wahrscheinlich erwähnen sollen. Das liegt daran, dass q bereits ein Makro enthält, das ausgeführt wird, während Sie aufnehmen, und es durcheinander bringt. Ich habe hier erklärt, wie man das umgeht
DJMcMayhem

1
@ LordAro Oh, duh, ich weiß, was das verursacht. Ich habe geändert df<space>, dWum ein Byte zu speichern, aber ich habe vergessen, dass df<space>das in Zeile 6 aus dem Makro ausbricht, aber dWnicht. Ich werde eine Revision zurücksetzen. Vielen Dank für den Hinweis!
DJMcMayhem

1
Dies ist zwar nicht ganz die kürzeste Antwort, aber bei weitem die beeindruckendste.
Isaacg

10

Retina, 108 104 100 69 Bytes

Die Anzahl der Bytes setzt die Kodierung nach ISO 8859-1 voraus.

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

Schlagen Sie das, PowerShell ...

Code Erklärung

Erste Linie: ].+{((\S+ ?)+)

Erstens müssen wir den Typ, den Array-Namen und die öffnende Klammer beibehalten (es wird ein Byte gespeichert), damit wir nicht mit ihnen übereinstimmen. Also haben wir den Schließbügel übereinstimmen, eine beliebige Anzahl von Zeichen und eine Öffnung geschweifte Klammer: ].+{. Dann passen wir die Nummernliste an. Kürzeste Ich habe in der Lage gewesen , so weit zu finden , ist dies: ((\S+ ?)+). Wir passen eine beliebige Anzahl von Nicht-Leerzeichen (dies beinhaltet Zahlen, mögliche negative Vorzeichen und mögliche Komma), gefolgt von einem Leerzeichen, das kann oder nicht sein kann: \S+ ?. Diese Zeichengruppe wird dann so oft wie nötig wiederholt (\S+ ?)+und in die große Erfassungsgruppe eingefügt. Beachten Sie, dass die schließende geschweifte Klammer oder das Semikolon nicht übereinstimmen. Die dritte Zeile erklärt, warum.

Zweite Reihe: $#2];$1

Da wir nur einen Teil der Eingabe abgeglichen haben, sind die nicht übereinstimmenden Teile weiterhin vorhanden. Also haben wir die Länge der Liste nach dem unübertroffenen Öffnungswinkel: $#2. Der Modifikator "Ersetzen" #hilft uns dabei, da er die Anzahl der Übereinstimmungen mit einer bestimmten Erfassungsgruppe angibt. In diesem Fall Erfassungsgruppe 2. Dann setzen wir eine abschließende Klammer und ein Semikolon und schließlich unsere ganze Liste.

Bei Eingabe short array[] = {4, 3, 2, 1};lautet die interne Darstellung nach diesem Ersetzen:

kurzes Array [4]; 4, 3, 2, 1};

(Beachten Sie die schließende geschweifte Klammer und das Semikolon)

Dritte Zeile: +`((\w+[).+;(\S+ )*)(-?\d+).+

Dies ist ein geschleifter Abschnitt. Das heißt, es wird solange ausgeführt, bis keine Stufe in der Schleife eine Änderung am Eingang vornimmt. Zuerst haben wir den Array - Namen übereinstimmen, durch eine öffnende Klammer gefolgt: (\w+\[). Dann kann eine beliebige Anzahl von beliebigen Zeichen und ein Semikolon: .+;. Dann passen wir die Liste wieder, aber diesmal nur Zahlen und das Komma nach jeder Nummer, die einen Raum hat sie zu folgen: (\S+ )*. Dann haben wir die letzte Nummer in der Liste erfassen: (-?\d+)und alle restlichen Zeichen dahinter: .+.

Vierte Zeile: $1¶$2$#3] = $4;

Wir ersetzen es dann mit dem Array - Namen und die Liste durch eine neue Zeile folgt: $1¶. Als nächstes haben wir den Array - Namen, durch die Länge des zuvor abgestimmten Liste folgt, ohne das letzte Element ( im wesentlichen list.length - 1): $2$#3. Gefolgt von einer schließenden Klammer und einem Zuweisungsoperator mit Leerzeichen, gefolgt vom letzten Element unserer Nummernliste:] = $4;

Nach dem ersten Ersetzen sieht die interne Darstellung folgendermaßen aus:

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

Beachten Sie, dass die schließende geschweifte Klammer und das Semikolon dank der .+am Ende der dritten Zeile verschwunden sind . Nach drei weiteren Ersetzungen sieht die interne Darstellung folgendermaßen aus:

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

Da in der dritten Zeile nichts mehr zu finden ist, ersetzt die vierte Zeile nichts und die Zeichenfolge wird zurückgegeben.

TL; DR: Zuerst ändern wir das Int-Listenformat ein bisschen. Dann nehmen wir das letzte Element der Liste und den Namen und setzen sie nach der Array-Initialisierung. Wir machen das so lange, bis die int-Liste leer ist. Dann geben wir den geänderten Code zurück.

Probieren Sie es online!


Jemand hat mich geschlagen ... :(
CalculatorFeline

M!`und G`sind ähnlich, aber nicht ganz gleich. Achtung.
CalculatorFeline

Die Erklärung in der dritten Zeile verwirrt mich. Der erste Punkt ist der einzige ohne Leerzeichen, nicht der letzte.
CalculatorFeline

@CatsAreFluffy Ich habe gerade versucht, den Wortlaut ein wenig zu ändern. Was ich meinte, war ein Leerzeichen nach einer Zahl, nicht davor. Ich glaube, ich habe die Bedeutung von "hinter" nicht vollständig verstanden. Ich sollte wirklich keine Code-Erklärungen um 2 Uhr morgens schreiben.
Daavko

@daavko "Behind" bedeutet normalerweise "after", dh "following" im umgangssprachlichen Englisch. Dir ging es gut.
Nic Hartley

9

V, 37 Bytes

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

V ist eine 2D-Saiten-basierte Golfsprache, die ich geschrieben habe und die aus vim entwickelt wurde. Dies funktioniert ab Commit 17 .

Erläuterung:

Dies ist so ziemlich eine direkte Übersetzung meiner vim-Antwort , wenn auch deutlich kürzer.

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

Dann haben wir einfach:

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

Da dieser Unicode-Wahnsinn schwer einzugeben sein kann, können Sie die Datei mit diesem umkehrbaren Hexdump erstellen:

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.

Dies kann ausgeführt werden, indem Sie V installieren und Folgendes eingeben:

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

1
Designed off of vim.2 Notizen: 1. Die meisten Leute sagen fromnicht off of, und 2. warum gab es das nicht. +1
Rɪᴋᴇʀ

8

C, 215 Bytes , 196 Bytes

Dank @tucuxi 19 Bytes gespart!

Golf gespielt:

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

Verknüpfung:

http://ideone.com/h81XbI

Erläuterung:

Um das zu bekommen <type> <array_name>, sscanf()lautet der Formatstring wie folgt:

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

Um die int-Werte aus der Zeichenfolge zu extrahieren int foo[] = {4, 8, 15, 16, 23, 42};, tokenisiere ich die Zeichenfolge im Wesentlichen mit dieser Funktion:

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

woher:

  • iist die Eingabezeichenfolge (a char*)
  • t ist der Versatz der Zeigerposition von i
  • xist die tatsächliche intaus der Zeichenfolge analysiert
  • n ist die Gesamtzahl der Zeichen, einschließlich der gefundenen Ziffer

Die sscanf()Formatzeichenfolge bedeutet Folgendes:

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

Wenn Sie die Eingabezeichenfolge als Zeichenarray darstellen:

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

Wenn sich das int 4Element bei Index 13, 8bei Index 16 usw. befindet, sieht das Ergebnis jedes Durchlaufs in der Schleife folgendermaßen aus:

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
Sie können die Verwendung von strcat vermeiden, indem Sie oinnerhalb von sprintf über verketten %s. Dies sollte etwa 7 Zeichen rasieren.
Tucuxi

@tucuxi Ah, guter Fang. Vielen Dank!
Homersimpson

7

C 195 180 Bytes

195-Byte-Original:

Golf gespielt:

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
}

Die beiden Verknüpfungen verwenden den mModifikator, um ScanFs %szu veranlassen, ihren eigenen Speicher zuzuweisen (spart das Deklarieren von Char-Arrays), und verwenden strtok(der standardmäßig auch ohne Includes verfügbar ist ), um den Nummernanalyseteil durchzuführen .


180-Byte-Aktualisierung:

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

Verwendet die Idee von bnf679, an einen String anzuhängen, um keine Kommas zählen zu müssen.


6

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

Macht viel Gebrauch von F-Strings .

Ungolfed-Version:

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, ich habe F-Saiten vergessen. Diese werden für das Golfen sehr nützlich sein!
Morgan Thrapp

Ich denke, Sie können ein Byte speichern, indem Sie ein Listenverständnis anstelle der normalen Schleife verwenden
someonewithpc

@someonewithpc: Nein, es würde tatsächlich 1 zusätzliches Byte hinzufügen
Vaultah

5

Ruby, 127 110 108 99 88 Bytes

Anonyme Funktion mit einem einzelnen Argument als Eingabe. Vollständiges Programm, liest die Eingabe von STDIN. (Wenn Sie Rohr eine Datei in ist das Newline optional.) Returns Druckt die Ausgabezeichenfolge.

@TimmyD prahlte damit, dass seine Lösung alle anderen Nicht-Esolangs als Herausforderung geschlagen hatte, und überwand schließlich die (zum Zeitpunkt des Schreibens) 114-Byte-Powershell-Lösung, die sie veröffentlicht hatten. Cᴏɴᴏʀ O'Bʀɪᴇɴs Trick mit dem Aufteilen ]und Spleißen der zweiten Hälfte, um die Zahlen zu verbessern .

Ich muss den splat Operator mehr benutzen. Es ist so nützlich!

Entlehnt einen Trick aus der JavaScript ES6-Antwort von @ Neil, um mehr Bytes zu sparen, indem nach Wörtern gescannt wird, anstatt gsubund zu verwenden split.

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

AFAICT die Aufgabe ist es, ein vollständiges Programm zu schreiben.
Gewölbe

@vaultah Die Standardeinstellung für Code Golf ist ein Programm oder eine Funktion
Mego

@ Mego: die OP sagte "Sie müssen ein Programm schreiben"
Vaultah

@vaultah Normalerweise würde ich sagen, dass Code Golf mir erlaubt, eine Funktion zu verwenden, aber ein volles Programm hat mir 2 Bytes gespart, also warum nicht?
Value Ink

Ich glaube nicht, dass PowerShell dazu in der Lage ist. Haben Sie ein +1
AdmBorkBork

4

05AB1E , 52 50 47 Bytes

Code:

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

Verwendet die CP-1252- Codierung. Probieren Sie es online! .


1
Es ist so weit gekommen, dass ich alle anderen Antworten überspringe und nur noch nach Ihren 05AB1E-Antworten suche. Die Sprache fasziniert mich absolut.
WorseDoughnut

1
@WorseDoughnut Danke! Das ist das Schönste, was mir jemals jemand über 05AB1E gesagt hat :)!
Adnan

4

JavaScript (ES6), 100 Byte

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

Da nur die Wörter wichtig sind, werden einfach alle Wörter in der Originalzeichenfolge sowie führende Minuszeichen abgeglichen und das Ergebnis erstellt. (Ich dachte ursprünglich, ich würde verwenden, replaceaber das stellte sich als roter Hering heraus.)


[t,n,...m]Fast eine mystische Vision
edc65

4

Pyth - 53 50 46 45 44 Bytes

2 Bytes gespart dank @FryAmTheEggman.

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

Test Suite .


4

Pip , 48 47 Bytes

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

Übernimmt die Eingabe von stdin und druckt auf stdout.

Erläuterung

Tl; dr: Führt eine Regex-Ersetzung durch, wobei Erfassungsgruppen und eine Rückruffunktion verwendet werden, um das Ergebnis zu erstellen.

Die qspezielle Variable liest eine Eingabezeile. Der reguläre Ausdruck ist (\S+)(. = ).(.+)}, der mit allen Zeichen außer dem Typ (einschließlich Leerzeichen) und dem abschließenden Semikolon übereinstimmt. Unter Verwendung des ersten Beispiel von der Frage, bekommen die diesen Gruppen foo[, ] = und 4, 8, 15, 16, 23, 42.

Die Ersetzung ist der Rückgabewert der unbenannten Funktion {[b#Yd^k']';.n.b.,#y.c.y]}, die mit der gesamten Übereinstimmung plus den Erfassungsgruppen als Argumente aufgerufen wird. Ruft innerhalb der Funktion die bErfassungsgruppe 1, die cGruppe 2 und die dGruppe 3 ab.

Wir bauen eine Liste, die ersten drei Punkte von denen sein "foo[", 6und "]". Um das zu erhalten 6, teilen wir ddie eingebaute Variable k= auf ", ", Yverknüpfen die resultierende Liste von Ganzzahlen mit der yVariablen für die zukünftige Verwendung und nehmen die Länge ( #). ']ist ein buchstäbliches Zeichen.

Was bleibt, ist eine Reihe von Zeichenfolgen der Form zu konstruieren ";\nfoo[i] = x". Dazu verketten wir folgendes: ';, n(a built-in für Newline), b(1. Capture - Gruppe), ,#y(entspricht Python range(len(y))), c(2. Capture - Gruppe), und y. Die Verkettung funktioniert bei Listen und Bereichen elementweise. Das Ergebnis ist eine Liste von Zeichenfolgen. Alles in allem ist der Rückgabewert der Funktion eine Liste wie die folgende:

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

Da diese Liste in einer Zeichenfolge Rverwendet wird, wird sie implizit in eine Zeichenfolge umgewandelt. Die Standardkonvertierung von Liste in Zeichenfolge in Pip verkettet alle Elemente:

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

Schließlich wird das Ergebnis (einschließlich des Typs und des letzten Semikolons, die von der Regex nicht übereinstimmten und daher unverändert bleiben) automatisch gedruckt.


4

Perl 5.10, 73 72 68 66 + 1 (für -n Schalter) = 67 Bytes

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

Dies ist eine schöne Herausforderung für Perl und die bisher kürzeste unter den Mehrzwecksprachen. Gleichwertig

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

4

PowerShell v2 +, 114 - 105 Byte

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

Nimmt die Eingabezeichenfolge $argsund -replaces die eckige Klammer mit nichts und führt dann ein -splitOn-Whitespace aus. Wir speichern das erste Bit in $a, das zweite Bit in $b, das =In $cund die Array-Elemente in $d. Im folgenden Beispiel wird dies fooin $aund barin $bsowie das gesamte Array in gespeichert $d.

Wir geben dann unsere erste Zeile mit "$a ..."und in der Mitte als Transformation $dvon einem Array von Zeichenfolgen der Form {1,, 2,... 100};in ein reguläres int-Array aus, indem -joinwir sie zu einer Zeichenfolge zusammenfassen und dann iexzweimal durchlaufen (ähnlich wie eval). Wir speichern das resultierende Array wieder in, $dbevor wir die .lengthMethode aufrufen , um die entsprechende Zahl []in der Ausgabezeile einzufügen.

Wir senden dann $ddurch eine Schleife mit |%{...}. Jede Iteration wird "$b..."mit einer $iin Klammern eingeschlossenen Zählervariable und dem aktuellen Wert ausgegeben $_. Die $iVariable startet nicht initialisiert (äquivalent zu $null), aber sie ++wird intvor der Ausgabe in ein umgewandelt, so dass sie bei 0allen vor dem Inkrementieren $ifür die nächste Schleifeniteration mit der Ausgabe beginnt .

Alle Ausgabezeilen verbleiben in der Pipeline, und die Ausgabe an das Terminal erfolgt implizit bei Programmbeendigung.

Beispiel

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;

Wütend! Ich habe es geschafft, meine Ruby-Antwort an Ihrer vorbeiziehen zu lassen, indem ich Ihren Kommentar, die anderen Nicht-Esolangs zu schlagen, als Herausforderung betrachtete! Gute Arbeit, aber +1.
Value Ink

@ KevinLau Danke! Zurück bei dir mit einer 105 jetzt. ;-)
AdmBorkBork

Ich rufe deine 105 an und erhöhe dich mit einer 99! : D
Value Ink

Wir nähern uns nicht mehr der schlagenden Retina.
CalculatorFeline

3

C 278-280 Bytes

Golf gespielt:

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

Während der Arbeit haben einige eine kürzere Version gepostet, die sscanf für das Parsen verwendet, anstatt Datenzeiger zu verwenden ... nett!

UPDATE: Beim Drucken von Elementen wurden fehlende Leerzeichen um den gleichen Wert gefunden . IDE-Online-Link: http://ideone.com/KrgRt0 . Beachten Sie, dass diese Implementierung negative Zahlen unterstützt ...


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}

Besser lesbar:

{
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
}
  • Ich setze das Feldtrennzeichen auf alles außer Buchstaben, Ziffern, Unterstrich und -. Die Felder wären also der Typname, der Variablenname und die Zahlen.
  • Die Anzahl der Felder ist 1 (für den Typ) + 1 (für den Namen) + N (Zahlen) + 1 (ein leeres Feld nach dem Ende };). Die Größe des Arrays ist also NF - 3.
  • Dann wird nur eine spezielle Zeile für die Deklaration gedruckt und die Zahlen durchlaufen.
  • Ich sollteFS entweder beim Aufruf von awk (using -F) oder in einem BEGINBlock zuweisen . Im Interesse der Kürze….

1
Eigentlich FSmuss entweder in zugewiesen werden BEGINoder verwendet werden, -Fsonst wird es nicht verwendet, um die erste Zeile zu teilen, und da es nur 1 Eingabezeile gibt ...
Robert Benson

@RobertBenson Sie haben Recht, also wäre der Befehl 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}', das sind 102 Bytes, die sich nicht awkselbst zählen. Hmmm. Kann ich die Anführungszeichen ausschließen?
muru

Ja, Sie können Anführungszeichen ausschließen. Sie listen es manchmal als C+O byteswo auf Cund Ostellen die Bytes aus Code bzw. Optionen dar. Natürlich benutze ich im Allgemeinen nur einen BEGINBlock, damit ich nicht darüber nachdenken muss. : p
Robert Benson

2

JavaScript ES6, 134 132 130 129 Bytes

1 Byte dank Neil gespeichert.

x=>(m=x.match(/(\w+) (\w+).+{(.+)}/),m[1]+` `+(q=m[2])+`[${q.length-1}];
`+m[3].split`, `.map((t,i)=>q+`[${i}] = ${t};`).join`
`)

Sollte nicht `[${i}] = `+t+";"sein `[${i}] = ${t};`?
Neil

@Neil Danke, ein Byte gespeichert!
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]/};"
}

Erster Versuch, sicher ist es möglich, es kürzer zu machen.


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

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

Ich weiß nicht, D, aber können Sie die öffnende eckige Klammer als Teil des Namens lesen? Das erspart Ihnen später das separate Schreiben einer eckigen Klammer.
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])

Dies ist eine Funktion, die eine Zeichenfolge akzeptiert und eine Zeichenfolge mit einer einzelnen nachgestellten Zeile zurückgibt.

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

Wir definieren c, dass es sich um ein Array von Übereinstimmungen der Eingabe im regulären Ausdruck handelt -?\w+. Es gibt den Typ, den Arraynamen und dann jeden Wert an. Wir speichern nals die Länge von c- 2, was die Anzahl der Werte ist. Die Ausgabe wird als interpolierte Zeichenfolge aus Typ, Name und Länge erstellt, wobei jede Definitionszeile durch Zeilenumbrüche getrennt wird. Aus welchem ​​Grund auch immer, c[]ist das gleiche wie c[1].

32 Bytes mit Hilfe von Dennis gespeichert!


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

Probieren Sie es online aus

Vielen Dank an Kevin Lau für einige Golfvorschläge


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

Teilt die Eingabe in den Typ, den Namen und die Liste der Nummern auf. Nachdem Sie die Array-Deklaration gedruckt haben, drucken Sie die Elemente, indem Sie die Zahlen manuell durchlaufen und dabei die überschüssige Interpunktion entfernen, die mit der ersten und der letzten verknüpft ist.

Ein anderer Ansatz in Python 2 ergab 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

Die Idee ist, evaldie Liste der Zahlen als Tupel mit einem Komma am Ende zu versehen, damit eine einzelne Zahl als Typ erkannt wird. Die aufgezählte Liste der Zahlen enthält Tupel, in denen Zeichenfolgen formatiert werden können.


1

PHP, 143 Bytes

Golf gespielt

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

Die Eingabe erfolgt über das Befehlszeilenargument. Probe:

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

Ausgabe:

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

Dies ist nicht C, aber es verwendet die C-ähnliche sprintfFunktion Nah, die 4 Bytes verschwendete.

Probieren Sie es 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))))

Ich war nicht in der Lage, schön zu verschmelzen awful_array_name[5];und awful_array_name[0] = 7;Teile , so dass sie wiederverwenden Code würde: /

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.