ขยายอาร์เรย์ C


36

ในภาษาการเขียนโปรแกรม C มีการกำหนดอาร์เรย์ดังนี้:

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

ขนาดของอาร์เรย์ถูกอนุมานจากองค์ประกอบการเริ่มต้นซึ่งในกรณีนี้คือ 6 คุณยังสามารถเขียนอาร์เรย์ C ด้วยวิธีนี้ปรับขนาดอย่างชัดเจนแล้วกำหนดขนาดองค์ประกอบตามลำดับ

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;

ความท้าทาย

คุณต้องเขียนโปรแกรมหรือฟังก์ชั่นที่ขยายอาร์เรย์จากวิธีแรกไปเป็นครั้งที่สอง เมื่อคุณเขียนโปรแกรมเพื่อสร้างรหัสให้ยาวขึ้นและคุณชอบประชดคุณต้องทำให้รหัสของคุณสั้นที่สุด

อินพุตจะเป็นสตริงที่แทนอาร์เรย์ดั้งเดิมและเอาต์พุตจะเป็นนิยามอาร์เรย์ที่ขยายเพิ่ม คุณสามารถสรุปได้ว่าอินพุตจะมีลักษณะดังนี้:

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

"Type" และ "array_name" จะประกอบด้วยตัวอักษรและขีดล่าง_ทั้งหมด องค์ประกอบของรายการจะเป็นตัวเลขในช่วง -2,147,483,648 ถึง 2,147,483,647 เสมอ อินพุตในรูปแบบอื่นไม่จำเป็นต้องได้รับการจัดการ

ช่องว่างในผลลัพธ์ของคุณจะต้องตรงกับช่องว่างในผลลัพธ์การทดสอบแม้ว่าบรรทัดใหม่ต่อท้ายจะได้รับอนุญาต

ทดสอบ 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;

สนับสนุนการส่งในภาษาใด ๆ แต่จะได้รับคะแนนโบนัสหากคุณสามารถทำได้ใน C

ลีดเดอร์บอร์ด:

นี่คือกระดานแต้มนำที่แสดงคำตอบยอดนิยม:


2
ช่องว่างระหว่างดัชนีอาเรย์, เครื่องหมายเท่ากับและค่าที่ต้องการในเอาต์พุตหรือไม่? ตัวอย่างเช่นจะfoo[0]=1;ยอมรับได้หรือไม่
Mego

@ Mego นั่นคงไม่เป็นที่ยอมรับ ต้องการพื้นที่ว่าง ฉันจะแก้ไขสิ่งต่อไปนี้
DJMcMayhem

ขึ้นบรรทัดใหม่ที่อนุญาตหรือไม่
Luis Mendo

ฟังก์ชั่นอนุญาตหรือไม่
Mego

มันจะโอเคที่จะส่งคืนผลลัพธ์แทนที่จะพิมพ์หรือไม่? (ในกรณีของฟังก์ชั่น)
vaultah

คำตอบ:


12

Pyth, 44 ไบต์

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

ชุดทดสอบ

การแสดงออกปกติและการสับสตริง ไม่ฉลาดโดยเฉพาะอย่างยิ่ง

คำอธิบาย:

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

คำตอบนี้คือหนามอยู่ข้างฉัน ฉันคิดว่าฉันจะสามารถชนะได้เป็นกลุ่ม แต่สำหรับชีวิตของฉันฉันไม่สามารถละ 2-3 ไบต์สุดท้ายได้ = D คำตอบที่ดี!
DJMcMayhem

28

เป็นกลุ่ม, 54, 52, 49 47 การกดแป้น


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

คำอธิบาย:

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

ตอนนี้บัฟเฟอร์ของเรามีลักษณะดังนี้:

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

และเคอร์เซอร์ของเราอยู่ในบรรทัดสุดท้าย

ครึ่งหลัง:

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

ตอนนี้ทุกอย่างดูดีเราต้องเพิ่ม array-declaration ดั้งเดิม ดังนั้นเราจึง:

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
เมื่อใดก็ตามที่ฉันอ่าน vim-golf ฉันตระหนักถึงการเข้ารหัสทั้งหมดที่ฉันทำ (ส่วนใหญ่คำสั่งแป้นพิมพ์ในตัวแก้ไข GUI เบ็ดเตล็ดของฉัน) มีลักษณะเช่นนี้และจิตใจของฉันโค้งงอเป็นเวลาหนึ่งนาที (Vim เป็นเพียงการทำให้สมบูรณ์ : P
cat

ฉันไม่สามารถใช้งานได้ - เมื่อฉันพิมพ์ "@q" ครั้งแรก (ของ "@ qq @ q") แมโครจะทำงานจากนั้นเห็นได้ชัดว่าทำงานได้ดีกว่าที่ควรจะได้รับสิ่งที่ชอบint foo[6] = {และลงท้ายด้วยint foo[12(เคอร์เซอร์บน "2")
LordAro

@ LordAro ฉันอาจจะต้องพูดถึงเรื่องนั้น นั่นเป็นเพราะมีมาโครใน q อยู่แล้วและมันทำงานในขณะที่คุณกำลังบันทึกทำให้สับสน ฉันอธิบายวิธีเดินทางรอบ ๆ ที่นี่: codegolf.stackexchange.com/a/74663/31716
DJMcMayhem

1
@ ลอร์ดโอโรใช่แล้วฉันรู้ว่าอะไรเป็นสาเหตุ ฉันเปลี่ยนdf<space>เป็นdWบันทึกไบต์ แต่ฉันลืมว่าdf<space>จะแยกแมโครออกจากบรรทัด 6 แต่dWไม่ได้ ฉันจะย้อนกลับการแก้ไข ขอบคุณสำหรับการชี้ให้เห็น!
DJMcMayhem

1
แม้ว่านี่จะไม่ใช่คำตอบที่สั้นที่สุด แต่ก็เป็นสิ่งที่น่าประทับใจที่สุด
isaacg

10

เรติน่า, 108 104 100 69 69 ไบต์

จำนวนไบต์ถือว่าการเข้ารหัส ISO 8859-1

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

เอาชนะสิ่งนี้ PowerShell ...

คำอธิบายรหัส

เส้นแรก: ].+{((\S+ ?)+)

อันดับแรกเราต้องเก็บประเภทชื่ออาร์เรย์และวงเล็บเปิด (ซึ่งจะช่วยประหยัดไบต์) ดังนั้นเราจึงไม่ตรงกับพวกเขา ดังนั้นเราจึงตรงกับวงเล็บปิดจำนวนตัวอักษรใด ๆ ].+{และการเปิดวงเล็บปีกกา: จากนั้นเราจับคู่รายการหมายเลข ((\S+ ?)+)ที่สั้นที่สุดที่ฉันได้รับสามารถที่จะหาเพื่อให้ห่างไกลคือ: เราตรงกับจำนวนอักขระที่ไม่ใช่พื้นที่ใด (ซึ่งรวมถึงตัวเลขเครื่องหมายลบเป็นไปได้และเป็นไปได้จุลภาค) \S+ ?ตามด้วยพื้นที่ที่อาจจะหรือไม่อาจจะมี: กลุ่มของอักขระนี้จะถูกทำซ้ำหลาย ๆ ครั้งตามต้องการ: (\S+ ?)+และใส่เข้าไปในกลุ่มการจับภาพขนาดใหญ่ โปรดทราบว่าเราไม่ตรงกับวงเล็บปีกกาปิดหรือเครื่องหมายอัฒภาค คำอธิบายบรรทัดที่สามบอกเหตุผล

บรรทัดที่สอง: $#2];$1

เนื่องจากเราจับคู่ส่วนของอินพุตเท่านั้นส่วนที่ไม่ตรงกันจะยังคงอยู่ที่นั่น $#2ดังนั้นเราจึงนำความยาวของรายการหลังจากที่วงเล็บเปิดเปรียบ: ตัวดัดแปลงแทนที่#ช่วยให้เรามีเช่นนั้นเพราะมันทำให้เรามีจำนวนการจับคู่กลุ่มจับภาพเฉพาะที่ทำ 2ในกลุ่มจับกรณีนี้ จากนั้นเราใส่วงเล็บปิดและเครื่องหมายอัฒภาคและท้ายที่สุดรายการทั้งหมดของเรา

ด้วยอินพุตshort array[] = {4, 3, 2, 1};การแทนค่าภายในหลังจากการแทนที่นี้คือ:

อาร์เรย์แบบสั้น [4]; 4, 3, 2, 1};

(บันทึกวงเล็บปีกกาปิดและอัฒภาค)

บรรทัดที่สาม: +`((\w+[).+;(\S+ )*)(-?\d+).+

นี่คือส่วนวนซ้ำ นั่นหมายความว่ามันจะทำงานจนกว่าจะไม่มีสเตจในลูปทำการเปลี่ยนแปลงอินพุต (\w+\[)ครั้งแรกที่เราตรงกับชื่ออาร์เรย์ตามด้วยวงเล็บเปิด: แล้วจำนวนข้อของตัวอักษรใด ๆ .+;และอัฒภาค: จากนั้นเราก็ตรงกับรายการอีกครั้ง (\S+ )*แต่คราวนี้เพียงตัวเลขและเครื่องหมายจุลภาคหลังจากที่ตัวเลขแต่ละตัวซึ่งมีพื้นที่ต่อไปนี้พวกเขา: แล้วเราจับหมายเลขสุดท้ายในรายการ: (-?\d+)และตัวอักษรใด ๆ .+ที่เหลืออยู่เบื้องหลังมัน:

บรรทัดที่สี่: $1¶$2$#3] = $4;

$1¶จากนั้นเราจะแทนที่ด้วยชื่ออาร์เรย์และรายชื่อตามด้วยขึ้นบรรทัดใหม่: ต่อไปเราจะใส่ชื่อของอาร์เรย์ตามความยาวของรายการจับคู่ก่อนหน้านี้โดยไม่ต้ององค์ประกอบสุดท้าย (หลัก):list.length - 1 $2$#3ตามด้วยวงเล็บปิดและโอเปอเรเตอร์ที่มีช่องว่างและตามด้วยองค์ประกอบสุดท้ายของรายการหมายเลขของเรา:] = $4;

หลังจากแทนที่ครั้งแรกการเป็นตัวแทนภายในจะมีลักษณะเช่นนี้:

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

โปรดทราบว่าวงเล็บปีกกาปิดและเครื่องหมายอัฒภาคหายไปขอบคุณ.+ที่ส่วนท้ายของบรรทัดที่สาม หลังจากการทดแทนอีกสามครั้งการเป็นตัวแทนภายในจะมีลักษณะดังนี้

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

เนื่องจากไม่มีอะไรที่จะเทียบได้กับบรรทัดที่สามอีกต่อไปที่สี่จึงไม่แทนที่สิ่งใดเลยและสตริงจะถูกส่งคืน

TL; DR:ก่อนอื่นเราเปลี่ยนรูปแบบรายการลิสต์ขึ้นเล็กน้อย จากนั้นเราจะใช้องค์ประกอบสุดท้ายของรายการและชื่อและวางไว้หลังจากการเริ่มต้นอาร์เรย์ เราทำสิ่งนี้จนกว่ารายการ int จะว่างเปล่า จากนั้นเราจะให้รหัสที่เปลี่ยนกลับ

ลองออนไลน์!


มีคนเอาชนะฉันได้ .... :(
เครื่องคิดเลข

M!`และG`มีความคล้ายคลึงกัน แต่ไม่เหมือนกัน ระวัง.
CalculatorFeline

คำอธิบายบรรทัดที่สามทำให้ฉันสับสน รายการแรกเป็นรายการเดียวที่ไม่มีช่องว่างด้านหลังไม่ใช่รายการสุดท้าย
CalculatorFeline

@CatsAreFluffy ฉันพยายามเปลี่ยนถ้อยคำขึ้นเล็กน้อยตอนนี้ สิ่งที่ฉันหมายถึงคือการเว้นวรรคตามหมายเลขไม่ใช่ก่อนหน้า ฉันเดาว่าฉันไม่ได้ตระหนักถึงความหมายของ "เบื้องหลัง" อย่างเต็มที่ ฉันไม่ควรเขียนคำอธิบายโค้ดตอนตีสอง
daavko

@daavko "Behind" โดยปกติหมายถึง "after" ie "follow" ในภาษาอังกฤษ คุณสบายดี
Nic Hartley

9

V, 37 ไบต์

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

V คือ 2D ภาษาที่ใช้เล่นกอล์ฟเป็นสตริงที่ฉันเขียนออกแบบมาเป็นกลุ่ม ผลงานนี้เป็นของกระทำ 17

คำอธิบาย:

นี่เป็นการแปลโดยตรงของคำตอบกลุ่มของฉันแม้ว่าจะสั้นกว่ามาก

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

จากนั้นเราก็มี:

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

เนื่องจากความบ้าคลั่งแบบ Unicode สามารถป้อนได้ยากคุณสามารถสร้างไฟล์ด้วย hexdump ที่สามารถย้อนกลับได้:

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.

สิ่งนี้สามารถทำงานได้โดยการติดตั้ง V และพิมพ์:

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

1
Designed off of vim.2 บันทึกย่อ: 1. คนส่วนใหญ่บอกfromว่าไม่ได้off ofและ 2. ทำไมจึงไม่มีสิ่งนี้ +1
Rɪᴋᴇʀ

8

C, 215 ไบต์ , 196 ไบต์

บันทึกไปแล้ว 19 ไบต์ด้วย @tucuxi!

แข็งแรงเล่นกอล์ฟ:

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

Link:

http://ideone.com/h81XbI

คำอธิบาย:

ที่จะได้รับ<type> <array_name>การsscanf()สตริงรูปแบบนี้คือ:

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

เพื่อแยกค่า int จากสตริงint foo[] = {4, 8, 15, 16, 23, 42};ฉันเป็นหลัก tokenize สตริงด้วยฟังก์ชั่นนี้:

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

ที่อยู่:

  • iคือสตริงอินพุต (a char*)
  • t เป็นตำแหน่งตัวชี้ออฟเซ็ตของ i
  • xคือการintแยกวิเคราะห์จริงจากสตริง
  • n คือจำนวนอักขระทั้งหมดที่ใช้รวมถึงตัวเลขที่พบ

sscanf()สตริงรูปแบบหมายถึงนี้:

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

หากคุณมองเห็นสตริงอินพุตเป็นอาร์เรย์ถ่าน:

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

ด้วยint 4การอยู่ที่ดัชนี 13, 8ที่ดัชนี 16, และอื่น ๆ นี่คือผลลัพธ์ของการรันในลูปแต่ละครั้งดังนี้:

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
คุณสามารถหลีกเลี่ยงการใช้ strcat ขึ้นโดยเชื่อมโยงoภายใน sprintf %sผ่าน ซึ่งควรโกนได้ประมาณ 7 ตัวอักษร
tucuxi

@tucuxi อ่าจับได้ดี ขอบคุณ!
homersimpson

7

C, 195 180 ไบต์

195- ไบต์ดั้งเดิม:

แข็งแรงเล่นกอล์ฟ:

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
}

ช็อตคัตสองตัวกำลังใช้mตัวแก้ไขเพื่อรับ scanf %sเพื่อจัดสรรหน่วยความจำของตัวเอง (บันทึกการประกาศอาร์เรย์ char) และการใช้strtok(ซึ่งยังมีให้ตามค่าเริ่มต้นโดยไม่รวมถึง) เพื่อทำส่วนการแยกวิเคราะห์ตัวเลข


การปรับปรุง 180 ไบต์:

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

ใช้แนวคิดของ bnf679ต่อท้ายสตริงเพื่อหลีกเลี่ยงการนับคอมม่า


6

Python 3.6 (เผยแพร่ล่วงหน้า), 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]};')

ทำให้การใช้f- สตริงอย่างหนัก

เวอร์ชันที่ไม่ถูกปรับแต่ง:

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
ว้าวฉันลืมเกี่ยวกับ f-strings สิ่งเหล่านี้จะเป็นประโยชน์อย่างมากสำหรับการเล่นกอล์ฟ!
Morgan Thrapp

ฉันคิดว่าคุณสามารถบันทึก byte โดยใช้ list comprehension แทนการวนซ้ำปกติ
someonewithpc ที่

@someonewithpc: ไม่จริงมันจะเพิ่ม 1 ไบต์พิเศษ
vaultah

5

ทับทิม, 127 110 108 99 88 ไบต์

ฟังก์ชั่นไม่ระบุชื่อที่มีอาร์กิวเมนต์เดียวเป็นอินพุต โปรแกรมแบบเต็มอ่านอินพุตจาก STDIN (หากคุณไพพ์ไฟล์เข้ามาบรรทัดใหม่ต่อท้ายจะเป็นทางเลือก) ส่งคืนพิมพ์สตริงเอาต์พุต

เอา @TimmyD คุยโวเกี่ยวกับการแก้ปัญหาของพวกเขาตีคนอื่น ๆ ที่ไม่ใช่ esolangs เป็นความท้าทายและในที่สุดก็เอาชนะ (ในขณะที่เขียน) 114 byte Powershell โซลูชั่นที่พวกเขาได้โพสต์ เคล็ดลับของCᴏɴᴏʀO'Bʀɪᴇɴเมื่อแยก]และต่อครึ่งหลังเพื่อรับหมายเลขช่วย

ฉันต้องใช้ตัวดำเนินการสีแดงมากขึ้น มันมีประโยชน์มาก!

ยืมเคล็ดลับจากคำตอบ JavaScript ของ ES6 ของ @ Neil เพื่อประหยัดไบต์มากขึ้นโดยสแกนหาคำแทนที่จะใช้gsubและsplit..

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

AFAICT ภารกิจนี้คือการเขียนโปรแกรมแบบเต็ม
vaultah

@vaultah ค่าเริ่มต้นสำหรับ code golf เป็นโปรแกรมหรือฟังก์ชั่น
Mego

@Mego: OP กล่าวว่า"คุณต้องเขียนโปรแกรม"
vaultah

@vaultah ปกติฉันจะบอกว่า code golf ช่วยให้ฉันใช้ฟังก์ชั่นได้ แต่โปรแกรมเต็มช่วยฉันด้วย 2 ไบต์แล้วทำไมล่ะ?
หมึกมูลค่า

Ooof ... ฉันไม่คิดว่า PowerShell สามารถลงไปได้ มี +1
AdmBorkBork

4

05AB1E , 52 50 47 ไบต์

รหัส:

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

ใช้การเข้ารหัสCP-1252 ลองออนไลน์! .


1
ได้มาถึงจุดที่ฉันข้ามคำตอบอื่น ๆ ทั้งหมดเพียงแค่มองหาคำตอบ 05AB1E ของคุณ ภาษานั้นทำให้ฉันหลงใหล
WorseDoughnut

1
@WordDoughnut ขอขอบคุณ! นั่นคือสิ่งที่ดีที่สุดที่ใครบางคนเคยบอกกับฉันเกี่ยวกับ 05AB1E :)!
Adnan

4

JavaScript (ES6), 100 ไบต์

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

เนื่องจากคำเหล่านี้มีความสำคัญเพียงอย่างเดียวงานนี้ทำได้โดยการจับคู่คำทั้งหมดในสตริงดั้งเดิมบวกกับเครื่องหมายลบที่นำหน้าแล้วสร้างผลลัพธ์ (ตอนแรกฉันคิดว่าฉันจะใช้replaceแต่นั่นกลายเป็นปลาเฮอริ่งแดง)


[t,n,...m]เกือบเป็นวิสัยทัศน์ที่ลึกลับ
edc65


4

Pip , 48 47 ไบต์

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

รับอินพุตจาก stdin และพิมพ์ไปยัง stdout

คำอธิบาย

Tl; dr:ทำการแทนที่ regex โดยใช้กลุ่มการดักจับและฟังก์ชันการเรียกกลับเพื่อสร้างผลลัพธ์

qตัวแปรพิเศษอ่านบรรทัดของการป้อนข้อมูล regex คือ(\S+)(. = ).(.+)}ซึ่งจับคู่ทุกอย่างยกเว้นประเภท (รวมถึงช่องว่างต่อท้าย) และเครื่องหมายอัฒภาคสุดท้าย ใช้ตัวอย่างแรกจากคำถามที่ว่ากลุ่มจับได้รับfoo[, และ] = 4, 8, 15, 16, 23, 42

การแทนที่คือค่าส่งคืนของฟังก์ชันที่ไม่มีชื่อ{[b#Yd^k']';.n.b.,#y.c.y]}ซึ่งถูกเรียกด้วยการจับคู่ทั้งหมดพร้อมกับกลุ่มการดักจับเป็นอาร์กิวเมนต์ ดังนั้นภายในฟังก์ชั่นbรับกลุ่มที่ 1 cได้รับกลุ่มที่ 2 และdได้รับกลุ่มที่ 3

เราสร้างรายการที่สามรายการแรกที่จะ"foo[", และ6 "]"เพื่อให้ได้6เราแบ่งdตัวแปรบิวด์อินk= ", ", Yส่งผลให้รายการจำนวนเต็มเป็นyตัวแปรสำหรับใช้ในอนาคตและรับความยาว ( #)']เป็นตัวอักษรที่แท้จริง

";\nfoo[i] = x"สิ่งที่เหลืออยู่คือการสร้างชุดของสตริงของรูปแบบ ต้องการทำเช่นนั้นเราจะเชื่อมต่อไปนี้: ';, n(ในตัวสำหรับการขึ้นบรรทัดใหม่) b(กลุ่มที่ 1 จับ) ,#y(เทียบเท่า Python range(len(y))) c(กลุ่มการจับภาพที่ 2) yและ การต่อข้อมูลทำงานตามเข็มนาฬิกาในรายการและช่วงดังนั้นผลลัพธ์คือรายการสตริง เมื่อรวมทั้งหมดเข้าด้วยกันค่าส่งคืนของฟังก์ชันจะเป็นรายการเช่นนี้:

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

เนื่องจากรายการนี้ถูกใช้ในการจัดRเรียงสตริงจึงมีการส่งไปยังสตริงโดยปริยาย การแปลง list-to-string เริ่มต้นใน Pip เชื่อมองค์ประกอบทั้งหมด:

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

ในที่สุดผลลัพธ์ (รวมถึงประเภทและเครื่องหมายอัฒภาคสุดท้ายซึ่งไม่ตรงกับ regex และยังคงไม่เปลี่ยนแปลง) จะถูกพิมพ์อัตโนมัติ


4

Perl 5.10, 73 72 68 66 + 1 (สำหรับ -n switch) = 67 ไบต์

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

นี่เป็นความท้าทายที่ดีสำหรับ Perl และสั้นที่สุดในบรรดาภาษาทั่วไป เทียบเท่ากับ

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

4

PowerShell v2 +, 114 105 ไบต์

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

ใช้สตริงอินพุต$argsและ-replaceวงเล็บเหลี่ยมไม่มีอะไรแล้วจึงทำ-splitบนช่องว่าง เราเก็บบิตแรกใน$aบิตที่สองเข้า$bที่=เข้าและองค์ประกอบอาร์เรย์ลง$c $dสำหรับตัวอย่างด้านล่างนี้เก็บfooเข้า$aและbarออก$bและอาร์เรย์ทั้งหมดลงใน$dและทั้งหมดของอาร์เรย์ลง

จากนั้นเราจะส่งออกบรรทัดแรกของเราด้วย"$a ..."และในการแปลงตรงกลาง$dจากอาร์เรย์ของสตริงของรูปแบบ{1,, 2,... 100};ไปยังอาร์เรย์ int ปกติโดย-joinผสานเข้าด้วยกันเป็นสตริงเดียวจากนั้นเรียกใช้ผ่านiexสองครั้ง (คล้ายกับeval) เราเก็บอาร์เรย์ผลลัพธ์ไว้$dก่อนที่จะเรียกใช้.lengthเมธอดเพื่อเติมจำนวนที่เหมาะสมระหว่าง[]ในบรรทัดเอาต์พุต

แล้วเราจะส่งผ่านห่วงด้วย$d |%{...}แต่ละผลผลิตซ้ำเรา"$b..."มีตัวแปรเคาน์เตอร์ห่อหุ้มในวงเล็บและค่าปัจจุบัน$i ตัวแปรเริ่มเตรียม (เทียบเท่า) แต่จะโยนมันทิ้งไปยังก่อนที่จะส่งออกจึงจะเริ่มการส่งออกที่ทั้งหมดก่อนที่เพิ่มขึ้น$_$i$null++int0$iสำหรับการย้ำห่วงถัดไป

บรรทัดเอาต์พุตทั้งหมดถูกทิ้งไว้บนไพพ์ไลน์และเอาต์พุตไปยังเทอร์มินัลจะมีความหมายเมื่อสิ้นสุดโปรแกรม

ตัวอย่าง

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;

ต๊าย! ฉันจัดการเพื่อให้ได้คำตอบ Ruby ของฉันเล่นกอล์ฟผ่านคุณโดยการแสดงความคิดเห็นของคุณเกี่ยวกับการตี esolangs อื่น ๆ ที่ไม่ใช่ความท้าทาย! แม้ว่าการทำงานที่ดีจะ +1
หมึกมูลค่า

@KevinLau ขอบคุณ! กลับมาที่คุณกับ 105 ตอนนี้ ;-)
AdmBorkBork

ฉันจะโทรหาคุณ 105 และเพิ่มคุณ 99! : D
Value Ink

ไม่ปิดการเต้น Retina
CalculatorFeline

3

C, 278 280 ไบต์

แข็งแรงเล่นกอล์ฟ:

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

ในขณะที่ทำงานกับใครบางคนนี้โพสต์รุ่นที่สั้นกว่าโดยใช้ sscanf สำหรับการแยกวิเคราะห์มากกว่าการใช้ตัวชี้ข้อมูล ... หนึ่งที่ดี!

UPDATE: ช่องว่างที่ขาดหายไปเห็นรอบเท่าเทียมในการพิมพ์องค์ประกอบที่เชื่อมโยง IDE ออนไลน์: http://ideone.com/KrgRt0 หมายเหตุการติดตั้งนี้รองรับตัวเลขติดลบ ...


2

Awk, 101 ไบต์

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

อ่านง่ายขึ้น:

{
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
}
  • -ผมตั้งคั่นสนามทุกอย่างยกเว้นตัวอักษรตัวเลขขีดและ ดังนั้นฟิลด์จะเป็นชื่อประเภทชื่อตัวแปรและตัวเลข
  • จำนวนของฟิลด์จะเป็น 1 (สำหรับประเภท) + 1 (สำหรับชื่อ) + N (ตัวเลข) + 1 (ฟิลด์ว่างหลังการตาม};) ดังนั้นขนาดของอาเรย์คือNF - 3ดังนั้นขนาดของอาร์เรย์คือ
  • จากนั้นเป็นเพียงการพิมพ์บรรทัดพิเศษสำหรับการประกาศและวนรอบตัวเลข
  • ฉันควรกำหนดFSทั้งเมื่อเรียกใช้ awk (โดยใช้-F) หรือในBEGINบล็อก เพื่อผลประโยชน์ของความกระชับ ...

1
อันที่จริงFSจะต้องกำหนดทั้งในBEGINหรือใช้-Fมิฉะนั้นจะไม่สามารถใช้ในการแยกบรรทัดแรกและเนื่องจากมีเพียง 1 สายของการป้อนข้อมูล ...
โรเบิร์ตเบนสัน

@ RobertBenson คุณถูกต้องดังนั้นคำสั่งจะ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 ไบต์ซึ่งไม่นับawkตัวเอง อืมม ฉันจะได้รับการยกเว้นคำพูดได้หรือไม่?
muru

ใช่คุณสามารถยกเว้นเครื่องหมายคำพูดได้ บางครั้งคุณทำรายการว่าเป็นC+O bytesที่ไหนCและOแทนไบต์จากรหัสและตัวเลือกตามลำดับ แน่นอนว่าโดยทั่วไปฉันแค่ใช้BEGINบล็อกดังนั้นฉันจึงไม่ต้องคิด : p
Robert Benson

2

JavaScript ES6, 134 132 130 129 ไบต์

บันทึก 1 ไบต์ขอบคุณ 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`
`)

ไม่ควร`[${i}] = `+t+";"จะเป็น`[${i}] = ${t};`?
Neil

@ Neil ขอบคุณบันทึกไบต์!
Conor O'Brien

2

ทุบตี, 133 129 ไบต์

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

ความพยายามครั้งแรกแน่ใจว่ามันเป็นไปได้ที่จะทำให้มันสั้นลง


2

D, 197 , 188 ไบต์

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

หรือ 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, ";");
}

ฉันไม่รู้ D แต่คุณสามารถอ่านวงเล็บเหลี่ยมเปิดซึ่งเป็นส่วนหนึ่งของชื่อได้หรือไม่ ที่จะช่วยให้คุณไม่ต้องเขียนวงเล็บเหลี่ยมแยกทีหลัง
DLosc

2

จูเลีย, 154 134 101 ไบต์

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

นี่คือฟังก์ชั่นที่ยอมรับสตริงและส่งคืนสตริงที่มีบรรทัดใหม่ต่อท้ายเดี่ยว

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

เรากำหนดให้เป็นอาร์เรย์ของการแข่งขันของการป้อนข้อมูลในการแสดงออกปกติc -?\w+มันระบุประเภทชื่ออาร์เรย์จากนั้นแต่ละค่า เราจัดเก็บnตามความยาวของc- 2 ซึ่งเป็นจำนวนค่า เอาต์พุตถูกสร้างขึ้นเป็นสตริงชนิดชื่อและความยาวที่สอดแทรกรวมกับแต่ละบรรทัดนิยามที่คั่นด้วยบรรทัดใหม่ สำหรับเหตุผลใดเป็นเช่นเดียวกับc[]c[1]

บันทึก 32 ไบต์ด้วยความช่วยเหลือจาก Dennis!


1

Python 2, 159 ไบต์

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

ลองออนไลน์

ขอบคุณ Kevin Lau สำหรับคำแนะนำการเล่นกอล์ฟ


1

Python 3, 116 ไบต์

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

แยกอินพุตเป็นประเภทชื่อและรายการตัวเลข หลังจากพิมพ์อาร์เรย์ที่ประกาศแล้วให้พิมพ์องค์ประกอบโดยการแจกแจงตัวเลขด้วยตนเองลบเครื่องหมายวรรคตอนที่เกินที่แนบกับตัวแรกและตัวสุดท้าย

วิธีการที่แตกต่างใน Python 2 มีขนาด 122 ไบต์:

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

แนวคิดคือevalรายการของตัวเลขเป็น tuple โดยมีเครื่องหมายจุลภาคท้ายเพื่อให้หมายเลขเดียวถูกจดจำเป็นประเภท รายการตัวเลขที่แจกแจงจะให้สิ่งอันดับเป็นรูปแบบสตริง


1

PHP, 143 ไบต์

แข็งแรงเล่นกอล์ฟ

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

อินพุตถูกใช้ผ่านอาร์กิวเมนต์บรรทัดคำสั่ง ตัวอย่าง:

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

เอาท์พุท:

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 ไบต์

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

นี่ไม่ใช่ C แต่ใช้sprintfฟังก์ชันC-like Nah ที่เสีย 4 ไบต์

ลองออนไลน์!

          % 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 ไบต์

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

ฉันไม่สามารถผสานawful_array_name[5];และawful_array_name[0] = 7;ส่วนต่าง ๆ ได้อย่างดีดังนั้นพวกเขาจึงต้องการใช้รหัสซ้ำอีกครั้ง: /

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.