Jimmy bu dizileri yıktı


23

İş arkadaşım Jimmy , C / C ++ için yeni. Aynı zamanda yavaş öğrenen biri. Şimdi, adil olmak gerekirse, kodu her zaman derlenir, ancak gerçekten özensiz alışkanlıkları vardır. Örneğin, herkes şöyle bir dizi tanımlayabileceğinizi bilir:

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

Jimmy hariç herkes. Bir dizi yapmanın tek yolunun böyle olduğuna ikna olmuş :

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

Bunu kod incelemesinde düzeltmeye devam ediyorum ama öğrenmiyor. Bu yüzden taahhütte bulunduğunda kendisi için bunu otomatik olarak yapan bir araç yazmanıza ihtiyacım var¹.

Meydan okuma

Tam bir program yazmanızı veya çok satırlı bir dizgede girdi olarak kullanılan ve C dizisinin daha kompakt sürümünü çıkaran bir işlev yazmanızı istiyorum. Girdi daima boşluk dahil bu formatı izleyecektir:

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;

Kısacası, giriş her zaman geçerli ve iyi tanımlanmış C olacaktır. Daha ayrıntılı olarak:

Tüm tanımlayıcılar sadece harflerden ve alt çizgilerden oluşacaktır. Uzunluk her zaman en az bir olacak ve hiçbir zaman sınırlayıcı veya sınırsız indeksler olmayacak. Dizinlerin sıralı olduğunu da varsayabilirsiniz. Örneğin:

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

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

ve

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

tümü geçersiz girdilerdir ve gönderiminizde tanımsız davranışlara neden olabilirler. Ayrıca, tüm sayıların geçerli ondalık sayılar, negatif veya pozitif olacağını varsayabilirsiniz. Girdide fazladan boşluk yok. Çıktı her zaman bu formatı izlemelidir, boşluk dahil:

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

İşte bazı örnek veriler:

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

Girişinizi ve çıkışınızı STDIN / STDOUT, fonksiyon argümanları ve dönüş değeri, dosya okuma ve yazma vb. Gibi herhangi bir makul formatta alabilirsiniz. Standart boşluklar geçerlidir. Bayt cinsinden en kısa cevap kazanır!


His Bu pasif-agresif ve berbat bir fikir. Sen mi değil benden bu fikri olsun.


8
Özür dilerim Jimmy
DJMcMayhem


@DLosc Ah, Jimmy'nin ön-senaryosunda kullandığı şey bu!
Bergi

9
Tabii ki Jimmy bir kod golfçü değil.
jimmy23013

Bu meydan okuma Jimmies'i gerçekten çok şaşırttı .
DanTheMan

Yanıtlar:


8

Vim, 43 36 bayt

Jimmy'ye bir senaryo vermenize gerek yok, sadece ona uygun bir metin editörü kullanmayı öğretin. (netlik için gerçek ifadeler)

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

Güzel! Bu özel durumda, eğlenceli, küçük bir kesmek olan, <C-a>daha kısa t]. Ayrıca, teknik olarak 2'ye ihtiyacın olduğunu düşünüyorum <cr>çünkü onay istiyor.
DJMcMayhem

Standart golf kodlama zorluklarına verilen Vim cevapları , bayt cinsinden skorlanmalıdır.
Martin Ender

Ayrıca, norm df=daha kısadırs/.*=//g
DJMcMayhem

1
Ayrıca, 3wC] = {<esc>daha kısadır <C-a>di]$s = {<esc>.
DJMcMayhem

1
@Geobits Emacs cevabın nerede?
Neil

7

CJam, 43 36 bayt

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

Çevrimiçi Örnek

Açıklama:

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

İlk CJam cevabımdaki gelişmeler için Martin Ender'e teşekkür ederim .


6

JavaScript (ES6), 65 64 63 bayt

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

5

Retina , 30 28 bayt

Bayt sayısı, ISO 8859-1 kodlamasını varsayar.

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

Çevrimiçi deneyin!

açıklama

Aşağıdaki girişi örnek olarak kullanacağız:

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

1. Aşama

\d+];¶.+ 
] = {

İlk satırda arkada bir boşluk olduğuna dikkat edin.

Takip eden bir sayıyı ];ve bir satır beslemeyi, ardından da bir sonraki satırdaki son boşluğa kadar olan her şeyi eşleştirerek başlıyoruz . Bu maç sadece ilk satırın sonunda bulunabilir (nedeniyle ];). Bunların hepsi ile değiştirilir ] = {. Yani, örnek girişimizi şu şekilde dönüştürür:

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

2. aşama

;¶.+=
,

Şimdi bir sonraki satıra ;kadar her şeyi eşleştirip a =ile değiştiriyoruz ,. Bu, dizgiyi şuna dönüştürür:

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

Sahne 3

;
};

Sol olduğunu tüm ucunu tespit ve biz sadece kalan değiştirerek bunu ;birlikte };:

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

5

Julia, 112 108 105 Bayt

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

açıklama

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(

Collect (eachmatch ()) yerine [eachmatch () ...] ve daha kısa bir regex değiştirerek baytlar kaydedildi


Merhaba, PPCG'ye hoş geldiniz! Bu harika bir ilk cevap gibi görünüyor. Benden +1. Zorluk, “ Girişinizi ve çıktınızı herhangi bir makul formatta alabilirsiniz ” derken, eachmatchişlev çağrısında virgül ayırıcıdan sonra daha az güzel bir çıktı ve -1 bayt için boşluk kaldırabilirsiniz . Julia'ya kendim programlamadım, ama bu yazıyı okumak için ilginç bulabilirsiniz: Julia'da golf oynamak için ipuçları . Tekrar hoşgeldiniz ve konaklamanızın tadını çıkarın. :)
Kevin Cruijssen

1
Nazik sözlerin için çok teşekkürler :) PPCG, araştırmak için eğlenceli görünüyordu, bu yüzden deneyeceğim. Mevcut değildi henüz bu yanıt için Julia seçti
nyro_0

Kullanımı matchallmuhtemelen sıçramaktan daha kısa olacaktır eachmatch.
Alex A.

önce matchall'ı kullanmaya çalıştım, ancak her eşleşmenin aksine regex grupları (özellikle parantezde özellikle ilgilendiğim kısım) kullanmama izin vermiyor. (ya da sadece belgelerde bulamadım?)
nyro_0

3

Lua, 121 Bayt.

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

Açıklaması

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

Toplu iş, 160 bayt

@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

Not: Satır set s=,bir boşlukla bitiyor. STDIN'de girişi ele alır. Garip hattı 3 girişi (örneğin alır int spam[6];ve değiştirir [içine [] = {&remsonuçlanan set s=int spam[] = {&rem 6];daha sonra iki ifadeleri olarak yorumlanır alır ki, set s=int spam[] = {ve rem 6];sonuncusu bir yorumdur. Daha sonra her hat için öncelikle alana metni silin (çünkü yapabilirsiniz =desende kullanmayın ve eşleştirme açgözlü değildir) ve değeri alın.


3

C, 121 bayt

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

Bana göre çok basit, akla gelen herhangi bir gelişme öneriniz.

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

Hızlı bir bakışta, işe yaramaz bir boşluk olduğunu görebiliyorum [:-1] for.
Yytsi

2

05AB1E , 31 30 28 bayt

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

açıklama

ž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

Çevrimiçi deneyin!

Adnan sayesinde bir bayt kaydedildi


žuDÀÀ„[]„{}bir bayt yerine :).
Adnan

@Adnan: Doğru, İyi yakalayın!
Emigna

2

Java 7, 159 158 149 154 bayt

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

Sayesinde birden fazla bayt kaydedildi @Cliffroot .

Ungolfed ve test kodu:

Burada dene.

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

Çıktı:

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

1
Birkaç bayt kurtardı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(".$","};");}
cliffroot

@cliffroot Teşekkürler! Yeniden kullanmak gibi Nitekim bazı güzel hileler Stringparametresinde ve son kömürü yerine "};");yerine ait "")+"};";.
Kevin Cruijssen

2

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

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

İhtiyaçlar -pve -0bayraklar çalıştırmak için. Örneğin :

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

1

Jöle , 27 bayt

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

Çevrimiçi deneyin!

açıklama

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

Java'da string manipülasyonu her zaman olduğu gibi cehennemdir.

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

Bu saf bir regex cevaptır. Tek bir birleştirilmiş Stringyapmak, sonra gerçekleştirmekreplaceXxx tamam olana kadar .

Test ve asılsız:

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

Jöle , 33 bayt

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

TryItOnline

Nasıl?

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

Aşağı seçmen - nesi var?
Jonathan Allan


0

JavaScript, 125 bayt

Biliyorum diğerlerinden daha uzun, ama gerçekten kullanmak istemiştim eval. Sadece eğlence için.

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

Çalıştırmak için aşağıdakini buraya yapıştırın :

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 bayt

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

Uzun işlev isimleri bunu öldürdü: D

Test vitrinlerini burada dene !


0

V , 25 , 24 bayt

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

Çevrimiçi deneyin! Bu, yazdırılamaz bir <esc>karakter içeriyor , bu yüzden burada bir hexdump:

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

Açıklama:

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:
                          };    "'};'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.