Latar Belakang
Untuk pengiriman kode-golf saya di C, saya memerlukan alat pemrosesan. Seperti di banyak bahasa lain, spasi putih sebagian besar tidak relevan dalam sumber C (tetapi tidak selalu!) - masih membuat kode jauh lebih mudah dipahami oleh manusia. Program C sepenuhnya golf yang tidak mengandung spasi kosong tunggal sering hampir tidak dapat dibaca.
Oleh karena itu, saya suka menulis kode saya dalam C untuk pengiriman kode-golf termasuk spasi dan kadang-kadang komentar, sehingga program membuat struktur yang komprehensif saat menulis. Langkah terakhir adalah menghapus semua komentar dan spasi kosong yang berlebihan. Ini adalah tugas yang membosankan dan tidak ada artinya yang harus dilakukan oleh magang program komputer.
Tugas
Tulis program atau fungsi yang menghilangkan komentar dan ruang kosong berlebihan dari beberapa sumber C "pra-golf" sesuai dengan aturan berikut:
- A
\
(garis miring terbalik) sebagai karakter terakhir dalam sebuah garis adalah garis lanjutan . Jika Anda menemukan ini, Anda harus memperlakukan baris berikut sebagai bagian dari baris logis yang sama (misalnya, Anda dapat menghapus\
dan mengikuti\n
(baris baru) sepenuhnya sebelum melakukan hal lain) - Komentar hanya akan menggunakan format satu baris, dimulai dengan
//
. Jadi untuk menghapusnya, Anda mengabaikan sisa baris logis di mana pun Anda menemukan di//
luar string literal (lihat di bawah). - Karakter
spasi adalah (spasi),
\t
(tab) dan\n
(baris baru, jadi di sini akhir dari baris logis). Saat Anda menemukan urutan spasi putih, periksa karakter non-spasi putih di sekitarnya. Jika
- keduanya adalah alfanumerik atau garis bawah (kisaran
[a-zA-Z0-9_]
) atau - keduanya
+
atau - keduanya
-
atau - yang sebelumnya adalah
/
dan yang berikutnya adalah*
lalu ganti urutannya dengan karakter spasi tunggal (
).
Jika tidak, hilangkan urutan sepenuhnya.
Aturan ini memiliki beberapa pengecualian :
- Arahan preprosesor harus muncul pada baris mereka sendiri di output Anda. Arahan preprosesor adalah garis yang dimulai dengan
#
. - Di dalam string literal atau karakter literal , Anda tidak harus menghapus spasi kosong. Setiap
"
(tanda kutip ganda) /'
(tanda kutip tunggal) yang tidak secara langsung didahului dengan jumlah garis miring terbalik yang aneh (\
) memulai atau mengakhiri string literal / karakter literal . Anda dijamin bahwa string dan karakter literal berakhir pada baris yang sama dengan yang mereka mulai. string literal dan literal karakter tidak dapat disarangkan, jadi'
di dalam string literal , serta"
di dalam literal karakter tidak memiliki arti khusus.
- keduanya adalah alfanumerik atau garis bawah (kisaran
Spesifikasi I / O
Input dan output harus berupa urutan karakter (string) termasuk karakter baris baru atau array / daftar string yang tidak mengandung karakter baris baru. Jika Anda memilih untuk menggunakan array / daftar, setiap elemen mewakili sebuah baris, sehingga baris baru tersirat setelah setiap elemen.
Anda dapat menganggap input tersebut adalah kode sumber program C yang valid. Ini juga berarti hanya berisi karakter, tab, dan baris ASCII yang dapat dicetak. Perilaku yang tidak terdefinisi pada input yang salah diijinkan.
Terkemuka dan trailing spasi / baris kosong yang tidak diperbolehkan .
Uji kasus
memasukkan
main() { printf("Hello, World!"); // hi }
keluaran
main(){printf("Hello, World!");}
memasukkan
#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)); }
keluaran
#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));}
memasukkan
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)); }
keluaran
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));}
memasukkan
x; #include <stdio.h> int main() { puts("hello // there"); }
keluaran
x; #include<stdio.h> int main(){puts("hello // there");}
input (contoh dunia nyata)
// 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(); } } }
keluaran
#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();}}}
Ini kode-golf , jadi jawaban tersingkat (dalam byte) yang valid akan menang.