Jimmy diese Arrays runter


23

Mein Kollege Jimmy ist ein bisschen neu in C / C ++. Er lernt auch langsam. Nun, um fair zu sein, sein Code wird immer kompiliert, aber er hat einige wirklich schlampige Gewohnheiten. Zum Beispiel weiß jeder, dass Sie ein Array wie folgt definieren können:

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

Alle außer Jimmy. Er ist überzeugt, dass der einzige Weg, ein Array zu erstellen, so ist:

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

Ich repariere das für ihn in der Code-Überprüfung, aber er wird es nicht lernen. Sie müssen also ein Tool schreiben, das dies bei einem Commit automatisch für ihn erledigt¹.

Die Herausforderung

Ich möchte, dass Sie entweder ein vollständiges Programm oder eine Funktion schreiben, die eine mehrzeilige Zeichenfolge als Eingabe verwendet und die kompaktere Version des C-Arrays ausgibt. Die Eingabe folgt immer diesem Format, einschließlich Leerzeichen:

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;

Kurz gesagt, die Eingabe ist immer gültig und gut definiert C. Ausführlicher:

Alle Bezeichner bestehen nur aus Buchstaben und Unterstrichen. Die Länge wird immer mindestens eins sein, und es werden niemals Indizes fehlen oder außerhalb der Grenzen liegen. Sie können auch davon ausgehen, dass die Indizes in Ordnung sind. Beispielsweise:

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

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

und

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

sind alle ungültigen Eingaben und können undefiniertes Verhalten in Ihrer Übermittlung verursachen. Sie können auch davon ausgehen, dass alle Zahlen gültige Dezimalzahlen sind, negative oder positive. Die Eingabe enthält keine überflüssigen Leerzeichen. Die Ausgabe sollte immer in diesem Format erfolgen, einschließlich Leerzeichen:

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

Hier sind einige Beispieldaten:

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

Sie können Ihre Eingabe und Ausgabe in jedem vernünftigen Format vornehmen, z. B. STDIN / STDOUT, Funktionsargumente und Rückgabewert, Dateien lesen und schreiben usw. Es gelten Standardlücken. Die kürzeste Antwort in Bytes gewinnt!


¹Das ist passiv-aggressiv und eine schreckliche Idee. Sie haben nicht diese Idee von mir.


8
Ich entschuldige
mich


@ DLosc Ah, das ist es, was Jimmy in seinem Pre-Commit-Skript verwendet!
Bergi

9
Natürlich ist Jimmy kein Code-Golfer.
Jimmy23013

Diese Herausforderung rauschte wirklich meine Jimmies .
DanTheMan

Antworten:


8

Vim, 43 36 Bytes

Sie müssen Jimmy kein Skript geben, bringen Sie ihm lediglich bei, einen geeigneten Texteditor zu verwenden. (Aus Gründen der Klarheit wird buchstäblich zurückgegeben)

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

Nett! In diesem speziellen Fall <C-a>ist kürzer als t], was ein lustiger kleiner Hack ist. Außerdem denke ich, dass Sie technisch 2 benötigen, <cr>da es um Bestätigung bittet.
DJMcMayhem

Vim-Antworten auf Standard- Code-Golf- Herausforderungen sollten in Bytes gewertet werden.
Martin Ender

Auch norm df=ist kürzer alss/.*=//g
DJMcMayhem

1
Auch 3wC] = {<esc>ist kürzer als <C-a>di]$s = {<esc>.
DJMcMayhem

1
@Geobits Wo ist deine Emacs Antwort?
Neil

7

CJam, 43 36 Bytes

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

Online-Beispiel

Erläuterung:

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

Ein großes Dankeschön an Martin Ender für die Verbesserungen bei meiner ersten CJam-Antwort.


6

JavaScript (ES6), 65 64 63 Bytes

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

5

Retina , 30 28 Bytes

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

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

Probieren Sie es online!

Erläuterung

Wir werden die folgende Eingabe als Beispiel verwenden:

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

Bühne 1

\d+];¶.+ 
] = {

Beachten Sie, dass in der ersten Zeile ein Leerzeichen steht.

Wir beginnen mit der Suche nach einer folgenden Zahl ];und einem Zeilenvorschub und dann nach dem letzten Leerzeichen in der nächsten Zeile. Diese Übereinstimmung kann nur am Ende der ersten Zeile gefunden werden (aufgrund der ];). All dies wird durch ersetzt ] = {. Das heißt, es transformiert unsere Beispieleingabe in:

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

Stufe 2

;¶.+=
,

Jetzt passen wir alles von a ;bis zur =nächsten Zeile an und ersetzen es durch a ,. Dadurch wird die Zeichenfolge in Folgendes umgewandelt:

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

Stufe 3

;
};

Alles was übrig bleibt ist das Ende zu reparieren und wir ersetzen das einzig verbleibende ;durch };:

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

5

Julia, 112 108 105 Bytes

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

Erläuterung

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(

Gespeicherte Bytes durch Ersetzen von collect (eachmatch ()) durch [eachmatch () ...] und durch einen kürzeren regulären Ausdruck


Hallo, willkommen bei PPCG! Das sieht nach einer großartigen ersten Antwort aus. +1 von mir. Da die Abfrage lautet " Sie können Ihre Eingabe und Ausgabe in jedem vernünftigen Format vornehmen ", können Sie das Leerzeichen nach dem Komma-Trennzeichen im eachmatchFunktionsaufruf für eine weniger hübsche Ausgabe und -1 Byte entfernen . Ich habe Julia noch nie selbst programmiert, aber es könnte Sie interessieren, diesen Beitrag zu lesen: Tipps zum Golfen in Julia . Nochmals herzlich willkommen und genießen Sie Ihren Aufenthalt. :)
Kevin Cruijssen

1
Vielen Dank für deine freundlichen Worte :) PPCG schien mir Spaß zu machen, also dachte ich, ich werde es versuchen. Wählte Julia für diese Antwort, da sie noch nicht vorhanden war
nyro_0

Verwenden matchallwäre wahrscheinlich kürzer als splatting eachmatch.
Alex A.

Ich habe zuerst versucht, matchall zu verwenden, aber ich verwende keine Regex-Gruppen (der Teil in der Klammer, an dem ich besonders interessiert bin) im Gegensatz zu eachmatch. (oder konnte ich es einfach nicht in der Dokumentation finden?)
nyro_0

3

Lua, 121 Bytes.

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

Erklärt

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

Batch, 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

Hinweis: Die Zeile set s=,endet mit einem Leerzeichen. Übernimmt die Eingabe für STDIN. Das seltsame Linie 3 nimmt die Eingabe (zB int spam[6];und ändert die [in [] = {&remwas set s=int spam[] = {&rem 6];die dann als zwei Aussagen interpretiert wird, set s=int spam[] = {und rem 6];, von denen die letztere ist ein Kommentar. Dann gilt für jede Zeile löschen wir den Text auf den ersten Platz (da kann man 't use =in a pattern and the matching is non-greedy) und extrahiere den Wert.


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

3

Python 112 111

Bitte schlagen Sie mir ganz unkompliziert Verbesserungen vor, die mir in den Sinn kommen.

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

Auf einen kurzen Blick sehe ich, dass es ein nutzloses Leerzeichen gibt [:-1] for.
Yytsi

2

05AB1E , 31 30 28 Bytes

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

Erläuterung

ž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

Probieren Sie es online!

Ein Byte dank Adnan gespeichert


žuDÀÀstatt „[]„{}speichert ein byte :).
Adnan

@Adnan: Richtig, guter Fang!
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("..$","};");}

Mehrere Bytes dank @cliffroot gespeichert .

Ungolfed & Testcode:

Probieren Sie es hier aus.

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

Ausgabe:

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

1
Einige Bytes gespeichertString 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 Danke! In der Tat einige nette Tricks wie die Wiederverwendung des Stringin-Parameters und das Ersetzen des letzten Zeichens durch "};");ein "")+"};";.
Kevin Cruijssen

2

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

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

Notwendigkeiten -pund -0Flaggen zum Laufen. Zum Beispiel :

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

1

Gelee , 27 Bytes

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

Probieren Sie es online!

Erläuterung

Ỵ         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 Bytes

String-Manipulation in Java ist wie immer die Hölle.

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

Dies ist eine reine Regex-Antwort. Erstellen Sie eine einzelne Verkettung Stringund führen replaceXxxSie diese aus , bis sie in Ordnung ist.

Testen und ungolfed:

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

Gelee , 33 Bytes

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

TryItOnline

Wie?

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

Daunenwähler - was ist daran falsch?
Jonathan Allan


0

JavaScript, 125 Byte

Ich weiß, es ist länger als andere, aber ich wollte es unbedingt benutzen eval. Nur zum Spaß.

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ügen Sie zum Ausführen Folgendes hier ein :

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

Lange Funktionsnamen haben dies getötet: D

Probieren Sie die Testfälle hier !


0

V , 25 , 24 Bytes

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

Probieren Sie es online! Dieser enthält ein nicht druckbares <esc>Zeichen, daher hier ein Hexdump:

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

Erläuterung:

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:
                          };    "'};'
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.