พื้นหลัง
สำหรับการส่งโค้ดกอล์ฟของฉันใน C ฉันต้องการเครื่องมือประมวลผล เช่นเดียวกับในหลายภาษาอื่น ๆ ช่องว่างส่วนใหญ่ไม่เกี่ยวข้องในซอร์ส C (แต่ไม่เสมอไป!) - ยังทำให้โค้ดสามารถเข้าใจได้ง่ายขึ้นสำหรับมนุษย์ โปรแกรม C ที่เล่นกอล์ฟอย่างเต็มที่ที่ไม่มีช่องว่างซ้ำซ้อนเดียวมักจะอ่านไม่ได้
ดังนั้นฉันชอบที่จะเขียนรหัสของฉันใน C สำหรับการส่งรหัสกอล์ฟรวมถึงช่องว่างและบางครั้งความคิดเห็นดังนั้นโปรแกรมเก็บโครงสร้างที่เข้าใจได้ในขณะที่เขียน ขั้นตอนสุดท้ายคือการลบความคิดเห็นทั้งหมดและช่องว่างที่ซ้ำซ้อน นี้เป็นงานที่น่าเบื่อและไม่สนใจซึ่งจริงๆควรจะทำโดยนักศึกษาฝึกงานโปรแกรมคอมพิวเตอร์
งาน
เขียนโปรแกรมหรือฟังก์ชั่นที่กำจัดความคิดเห็นและช่องว่างที่ซ้ำซ้อนจากบางแหล่ง "pre-golfed" C ตามกฎต่อไปนี้:
\
(ทับขวา) เป็นตัวสุดท้ายในสายเป็นความต่อเนื่องบรรทัด หากคุณพบสิ่งนี้คุณต้องถือว่าบรรทัดต่อไปนี้เป็นส่วนหนึ่งของสายตรรกะเดียวกัน(ตัวอย่างเช่นคุณสามารถลบ\
และต่อไปนี้\n
(ขึ้นบรรทัดใหม่) อย่างสมบูรณ์ก่อนที่จะทำสิ่งอื่นใด)//
ความคิดเห็นที่จะใช้รูปแบบหนึ่งบรรทัดที่เริ่มต้นด้วย ดังนั้นเมื่อต้องการลบออกคุณจะไม่สนใจส่วนที่เหลือของบรรทัดโลจิคัลที่ใดก็ตามที่คุณพบ//
นอกสตริงตัวอักษร (ดูด้านล่าง)- อักขระช่องว่างคือ
(ช่องว่าง),
\t
(แท็บ) และ\n
(ขึ้นบรรทัดใหม่ดังนั้นนี่คือจุดสิ้นสุดของบรรทัดตรรกะ) เมื่อคุณค้นหาลำดับของช่องว่างให้ตรวจสอบอักขระที่ไม่ใช่ช่องว่างที่ล้อมรอบ ถ้า
- ทั้งคู่เป็นตัวอักษรและตัวเลขหรือขีดล่าง (ช่วง
[a-zA-Z0-9_]
) หรือ - ทั้งสอง
+
หรือ - ทั้งสอง
-
หรือ - สิ่งที่มาก่อนคือ
/
และสิ่งที่ตามมาคือ*
จากนั้นแทนที่ลำดับด้วย
อักขระช่องว่าง ( )
มิฉะนั้นให้กำจัดลำดับทั้งหมด
กฎนี้มีข้อยกเว้นบางประการ :
- คำสั่งของโปรเซสเซอร์ล่วงหน้าจะต้องปรากฏในบรรทัดของตัวเองในผลลัพธ์ของคุณ สั่ง preprocessor
#
เป็นสายที่เริ่มต้นด้วย - ภายในตัวอักษรสตริงหรือตัวอักษรคุณไม่ควรลบช่องว่างใด ๆ ใด ๆ
"
(อ้างดับเบิล) /'
(อ้างเดียว) ที่ไม่ได้นำหน้าได้โดยตรงโดยเป็นเลขคี่ backslashes (\
) เริ่มต้นหรือปลายสตริงตัวอักษร / ตัวอักษรตัวอักษร คุณรับประกันได้ว่าสตริงและตัวอักษรจะลงท้ายด้วยบรรทัดเดียวกันกับที่เริ่มต้น สายอักขระตัวอักษรและตัวอักษรของตัวละครไม่สามารถซ้อนกันดังนั้น'
ภายในตัวอักษรสตริง , เช่นเดียวกับ"
ภายในของตัวละครตัวอักษรไม่ได้มีความหมายพิเศษใด ๆ
- ทั้งคู่เป็นตัวอักษรและตัวเลขหรือขีดล่าง (ช่วง
ข้อกำหนด I / O
อินพุตและเอาต์พุตต้องเป็นลำดับอักขระ (สตริง) รวมถึงอักขระขึ้นบรรทัดใหม่หรืออาร์เรย์ / รายการสตริงที่ไม่มีอักขระขึ้นบรรทัดใหม่ หากคุณเลือกที่จะใช้อาร์เรย์ / รายการแต่ละองค์ประกอบแสดงถึงบรรทัดดังนั้นการขึ้นบรรทัดใหม่ที่มีนัยหลังจากที่แต่ละองค์ประกอบ
คุณอาจสันนิษฐานว่าอินพุตเป็นซอร์สโค้ดโปรแกรม C ที่ถูกต้อง นอกจากนี้ยังหมายความว่ามีเพียงอักขระ ASCII ที่พิมพ์ได้แท็บและการขึ้นบรรทัดใหม่ พฤติกรรมที่ไม่ได้กำหนดบนอินพุตที่มีรูปแบบไม่ได้รับอนุญาต
ชั้นนำและต่อท้ายช่องว่าง / บรรทัดว่างจะไม่ได้รับอนุญาต
กรณีทดสอบ
อินพุต
main() { printf("Hello, World!"); // hi }
เอาท์พุต
main(){printf("Hello, World!");}
อินพุต
#define max(x, y) \ x > y ? x : y #define I(x) scanf("%d", &x) a; b; // just a needless comment, \ because we can! main() { I(a); I(b); printf("\" max \": %d\n", max(a, b)); }
เอาท์พุต
#define max(x,y)x>y?x:y #define I(x)scanf("%d",&x) a;b;main(){I(a);I(b);printf("\" max \": %d\n",max(a,b));}
อินพุต
x[10];*c;i; main() { int _e; for(; scanf("%d", &x) > 0 && ++_e;); for(c = x + _e; c --> x; i = 100 / *x, printf("%d ", i - --_e)); }
เอาท์พุต
x[10];*c;i;main(){int _e;for(;scanf("%d",&x)>0&&++_e;);for(c=x+_e;c-->x;i=100/ *x,printf("%d ",i- --_e));}
อินพุต
x; #include <stdio.h> int main() { puts("hello // there"); }
เอาท์พุต
x; #include<stdio.h> int main(){puts("hello // there");}
อินพุต (ตัวอย่างจริง)
// often used functions/keywords: #define P printf( #define A case #define B break // loops for copying rows upwards/downwards are similar -> macro #define L(i, e, t, f, s) \ for (o=i; o e;){ strcpy(l[o t], l[o f]); c[o t]=c[s o]; } // range check for rows/columns is similar -> macro #define R(m,o) { return b<1|b>m ? m o : b; } // checking for numerical input is needed twice (move and print command): #define N(f) sscanf(f, "%d,%d", &i, &j) || sscanf(f, ",%d", &j) // room for 999 rows with each 999 cols (not specified, should be enough) // also declare "current line pointers" (*L for data, *C for line length), // an input buffer (a) and scratch variables r, i, j, o, z, c[999], *C, x=1, y=1; char a[999], l[999][999], (*L)[999]; // move rows down from current cursor position D() { L(r, >y, , -1, --) r++ ? strcpy(l[o], l[o-1]+--x), c[o-1]=x, l[o-1][x]=0 : 0; c[y++] = strlen(l[o]); x=1; } // move rows up, appending uppermost to current line U() { strcat(*L, l[y]); *C = strlen(*L); L(y+1, <r, -1, , ++) --r; *l[r] = c[r] = 0; } // normalize positions, treat 0 as max X(b) R(c[y-1], +1) Y(b) R(r, ) main() { for(;;) // forever { // initialize z as current line index, the current line pointers, // i and j for default values of positioning z = i = y; L = l + --z; C = c + z; j = x; // prompt: !r || y/r && x > *C ? P "end> ") : P "%d,%d> ", y, x); // read a line of input (using scanf so we don't need an include) scanf("%[^\n]%*c", a) // no command arguments -> make check easier: ? a[2] *= !!a[1], // numerical input -> have move command: // calculate new coordinates, checking for "relative" N(a) ? y = Y(i + (i<0 | *a=='+') * y) , x = X(j + (j<0 || strchr(a+1, '+')) * x) :0 // check for empty input, read single newline // and perform <return> command: : ( *a = D(), scanf("%*c") ); switch(*a) { A 'e': y = r; x = c[r-1] + 1; B; A 'b': y = 1; x = 1; B; A 'L': for(o = y-4; ++o < y+2;) o<0 ^ o<r && P "%c%s\n", o^z ? ' ' : '>', l[o]); for(o = x+1; --o;) P " "); P "^\n"); B; A 'l': puts(*L); B; A 'p': i = 1; j = 0; N(a+2); for(o = Y(i)-1; o<Y(j); ++o) puts(l[o]); B; A 'A': y = r++; strcpy(l[y], a+2); x = c[y] = strlen(a+2); ++x; ++y; B; A 'i': D(); --y; x=X(0); // Commands i and r are very similar -> fall through // from i to r after moving rows down and setting // position at end of line: A 'r': strcpy(*L+x-1, a+2); *C = strlen(*L); x = 1; ++y > r && ++r; B; A 'I': o = strlen(a+2); memmove(*L+x+o-1, *L+x-1, *C-x+1); *C += o; memcpy(*L+x-1, a+2, o); x += o; B; A 'd': **L ? **L = *C = 0, x = 1 : U(); y = y>r ? r : y; B; A 'j': y<r && U(); } } }
เอาท์พุต
#define P printf( #define A case #define B break #define L(i,e,t,f,s)for(o=i;o e;){strcpy(l[o t],l[o f]);c[o t]=c[s o];} #define R(m,o){return b<1|b>m?m o:b;} #define N(f)sscanf(f,"%d,%d",&i,&j)||sscanf(f,",%d",&j) r,i,j,o,z,c[999],*C,x=1,y=1;char a[999],l[999][999],(*L)[999];D(){L(r,>y,,-1,--)r++?strcpy(l[o],l[o-1]+--x),c[o-1]=x,l[o-1][x]=0:0;c[y++]=strlen(l[o]);x=1;}U(){strcat(*L,l[y]);*C=strlen(*L);L(y+1,<r,-1,,++)--r;*l[r]=c[r]=0;}X(b)R(c[y-1],+1)Y(b)R(r,)main(){for(;;){z=i=y;L=l+--z;C=c+z;j=x;!r||y/r&&x>*C?P"end> "):P"%d,%d> ",y,x);scanf("%[^\n]%*c",a)?a[2]*=!!a[1],N(a)?y=Y(i+(i<0|*a=='+')*y),x=X(j+(j<0||strchr(a+1,'+'))*x):0:(*a=D(),scanf("%*c"));switch(*a){A'e':y=r;x=c[r-1]+1;B;A'b':y=1;x=1;B;A'L':for(o=y-4;++o<y+2;)o<0^o<r&&P"%c%s\n",o^z?' ':'>',l[o]);for(o=x+1;--o;)P" ");P"^\n");B;A'l':puts(*L);B;A'p':i=1;j=0;N(a+2);for(o=Y(i)-1;o<Y(j);++o)puts(l[o]);B;A'A':y=r++;strcpy(l[y],a+2);x=c[y]=strlen(a+2);++x;++y;B;A'i':D();--y;x=X(0);A'r':strcpy(*L+x-1,a+2);*C=strlen(*L);x=1;++y>r&&++r;B;A'I':o=strlen(a+2);memmove(*L+x+o-1,*L+x-1,*C-x+1);*C+=o;memcpy(*L+x-1,a+2,o);x+=o;B;A'd':**L?**L=*C=0,x=1:U();y=y>r?r:y;B;A'j':y<r&&U();}}}
นี่คือcode-golfดังนั้นคำตอบที่ถูกต้องสั้นที่สุด (เป็นไบต์) จึงจะชนะ