Menerangi Kamar Cermin

13

Tujuan

Dalam kompetisi ini, Anda diberi ruang acak dengan satu lilin di dalamnya. Tujuannya adalah untuk menulis program terpendek (ini golf) yang menentukan bagian mana dari ruangan yang diterangi oleh lilin, dengan mengganti titik-titik gelap dengan @'s. Program harus mengambil ruang dari STDIN, dengan output dicetak ke STDOUT.

Contoh Input / Kamar

+------+
|  C   |
|      +--+
|  \      |
+---------+

Lilin diwakili dengan C, dan dinding / cermin diwakili dengan |, -, /, atau \. Dindingnya sendiri adalah cermin. Sudut-sudut ruangan diwakili dengan a +.

Kamar tidak akan pernah memiliki dinding diagonal, dan cahaya tidak akan pernah bisa keluar dari ruangan.

Juga, karakter pertama pada sebuah garis selalu akan menjadi bagian dari dinding di luar ruangan. Karakter terakhir absolut pada setiap baris akan menjadi dinding seberang ruangan. Tidak ada karakter di antara keduanya yang akan berada di luar ruangan.

Cahaya dan Refleksi

Lilin memancarkan delapan (seperti laser) cahaya dalam delapan arah dasar: N, S, E, W, NE, SE, SW, dan NW. Sinar cahaya ini memantul dari cermin seperti yang dijelaskan di bawah ini:

Old Direction of Travel | Mirror | New Direction
N S E W NE SE SW NW       /        E W N S -- -- -- --
N S E W NE SE SW NW       \        W E S N -- -- -- --
N S E W NE SE SW NW       |        - - - - NW SW NE SW
N S E W NE SE SW NW       -        - - - - SE NE SW NE

A -mewakili cahaya yang diserap. Cahaya selalu diserap oleh C atau +. Penting untuk dicatat bahwa lampu memantulkan cermin hanya ketika menempati ruang yang sama dengan cermin. Aturan-aturan ini jauh lebih mudah dipahami ketika Anda menggambar refleksi di atas kertas.

Contoh Output

Sebagai output, program harus mencetak gambar ruangan yang diterangi, dengan bintik-bintik gelap ditulis sebagai @, bintik-bintik terang dibiarkan kosong, dan cermin tidak terpengaruh. Untuk contoh di atas, hasilnya adalah:

+------+
|  C   |
|@   @ +--+
| @\      |
+---------+

Ini berarti bahwa, jika Anda mengeluarkan sinar cahaya, mereka tidak akan pernah mencapai ruang yang ditandai @.

Lebih banyak contoh

Input:
+-----+
|     |
|     |
|  C  |
|     |
|     |
+-----+
Output:
+-----+
| @ @ |
|@   @|
|  C  |
|@   @|
| @ @ |
+-----+

Input:
+-----+
|  \  |
|/ C \+-+
|       |
|  \ - ++
+------+
Output:
+-----+
|  \ @|
|/ C \+-+
|      @|
| @\ -@++
+------+
PhiNotPi
sumber
Dalam contoh Anda, bukankah seharusnya sudut kiri bawah @juga?
Peter Taylor
1
@ Peter Taylor: Sinar SW memukul tempat itu.
Briguy37
3
Beruang beberapa kesamaan dengan tantangan Laser yang diterima dengan sangat baik di Stack Overflow . Cukup banyak kesamaan untuk membuat metode yang digunakan di dalamnya menarik dengan perbedaan yang cukup untuk memerlukan beberapa pemikiran yang cukup tentang bagaimana mereka dapat diterapkan.
dmckee --- ex-moderator kitten
Dapat menggunakan lebih banyak kasus validasi.
dmckee --- ex-moderator kitten
@ dmckee Saya menambahkan dua contoh lagi.
PhiNotPi

Jawaban:

2

Python, 292 karakter

import sys
R=''
for x in sys.stdin:R+='%-97s\n'%x[:-1].replace(' ','@')
M={'/':'-98/d','\\':'98/d'}
for d in(-98,-1,1,98,99,97,-97,-99):
 if d>98:M={'|':'d^2','-':'-d^2'}
 p=R.find('C')
 while 1:
  p+=d
  if R[p]in' @':R=R[:p]+' '+R[p+1:]
  elif R[p]in M:d=eval(M[R[p]])
  else:break
print R,

Membaca di dalam ruangan, membuatnya persegi panjang, lalu berjalan keluar dari lilin ke segala arah. M berisi karakter cermin aktif dan efeknya ( /\untuk arah mata angin, |-untuk yang lain)

Dapat menangani kamar hingga 97 karakter.

Keith Randall
sumber
2

c - 504

Bergantung pada semantik memanggil fungsi standar K&R. Implementasi sangat lurus ke depan kecuali untuk hal-hal biola dengan memantulkan sinar.

#define N M[x+y*97]
#define Y abs(y)
#define O M[c]==
#define E else break;
int j[]={-98,-97,-96,-1,1,96,97,98},c,x,y,p,s,M[9409];main(){for(;
(c=getchar())!=-1;){if(c==10)x=0,++y;else{if(c==67)p=x+y*97;if(c==32)
c=64;N=c;++x;}}for(x=0;x<8;++x){y=j[x];c=p;do{c+=y;if(O'@')M[c]=32;s=y/Y;
if(O 92)if(y%2){y=s*(98-Y);}E if(O'/')if(y%2){y=s*-(98-Y);}E if(O'|')
if(~y%2){y=s*(97+(97-Y));}E if(O'-')if(~y%2){y=s*-(97+(97-Y));}E}while
(!(O'+')&&!(O'C'));}for(y=0;x=0,N!=0;++y){for(;N!=0;++x)putchar(N);
putchar(10);}}

Tidak disatukan

//#include <stdio.h>
int j[]={ -98, -97, -96, /* Increments to move around the array */
           -1,       1,
           96,  97,  98},
  c, x, y, p, s, /* take advantage of static initialization to zero */
  M[9409]; /* treat as 97*97 */

main(){
  /* read the map */
  while((c=getchar())!=-1/*Assume the deffinition of EOF*/){
    /* putchar(c);  */
    if (c=='\n')
      x=0,++y;
    else {
      if (c=='C') p=x+y*97; /* set start position */
      if (c==' ') c='@'; /* The room starts dark */
      M[x+y*97]=c; ++x;
    }
  }
  /* printf("Start position is %d (%d, %d)\n",p,p%97,p/97); */
  /* Now loop through all the direction clearing '@' cells as we
   * encounter them 
   */
  for(x=0;x<8;++x){
    y=j[x];c=p; /* y the increment, c the position */
    /* printf("\tposition %d (%d, %d) '%c'\n",c,c%97,c/97,M[c]); */
    /* printf("\tdirection = %d (%d, %d)\n",y,-(abs(y)-97),(y+98)/97-1); */
    do {
      c+=y;
      /* printf("\t\tposition %d (%d, %d) '%c'\n",c,c%97,c/97,M[c]); */
      /* We ought to do bounds checking here, but we rely on  *
       * the guarantee that the room will be bounded instead. */
      if(M[c]=='@') M[c]=' ';
      /* The reflections are handles
       *   + Stop or not stop based on the even/oddness of the increment
       *   + New direction is a little fiddly, look for yourself
       */
      s=y/abs(y); /* sign of y (need for some reflections) */
      if (M[c]=='\\') if (y%2){ y=s* (98-abs(y));     }else break; 
      if (M[c]=='/')  if (y%2){ y=s*-(98-abs(y));     }else break; 
      if (M[c]=='|')  if (~y%2){y=s* (97+(97-abs(y)));}else break; 
      if (M[c]=='-')  if (~y%2){y=s*-(97+(97-abs(y)));}else break;  
      /* printf("\t\t\tdirection = %d (%d, %d)\n",y,97-abs(y),(y+98)/97-1); */
    } while (!(M[c]=='+')&&!(M[c]=='C'));
    /* printf("\t...hit a %c. Done\n",M[c]); */
  }
  /* print the result */
  for(y=0;x=0,M[x+y*97]!=0;++y){
    for(;M[x+y*97]!=0;++x)
      putchar(M[x+y*97]);
    putchar('\n');
  }
}

Validasi

$ gcc -g -o candle candle_golfed.c
$ for f in candle_room*; do (./candle < $f) ; done
+------+
|  C   |
|@   @ +--+
| @\      |
+---------+
+------+
|  C   |
|@   @ +--+
|  /@ @ @ |
+---------+
+------+
| @/   |
|@   @ +--+
|  C      |
+---------+
+------+
|  \@ @|
|@   @ +--+
|  C      |
+---------+
+-----+
| @ @ |
|@   @|
|  C  |
|@   @|
| @ @ |
+-----+
dmckee --- mantan kucing moderator
sumber