Chiếu sáng một căn phòng nhân đôi


13

Mục tiêu

Trong cuộc thi này, bạn được cung cấp một căn phòng ngẫu nhiên với một cây nến bên trong. Mục tiêu là viết chương trình ngắn nhất (đây là golf) để xác định phần nào của căn phòng được chiếu sáng bởi ngọn nến, bằng cách thay thế các điểm tối bằng @'s. Chương trình sẽ lấy một phòng từ STDIN, với đầu ra được in thành STDOUT.

Ví dụ đầu vào / phòng

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

Ngọn nến được thể hiện với một C, và các bức tường / cạo được đại diện với |, -, /, hoặc \. Các bức tường là gương. Các góc của căn phòng được đại diện với a +.

Các phòng sẽ không bao giờ có tường chéo và ánh sáng sẽ không bao giờ có thể thoát ra khỏi phòng.

Ngoài ra, nhân vật đầu tiên trên một dòng luôn luôn là một phần của bức tường ra khỏi phòng. Ký tự cuối cùng tuyệt đối trên mỗi dòng sẽ là bức tường đối diện của căn phòng. Không có nhân vật giữa hai người này sẽ ở bên ngoài phòng.

Ánh sáng và sự phản chiếu

Cây nến phát ra tám chùm ánh sáng (giống như tia laser) theo tám hướng cơ bản: N, S, E, W, NE, SE, SW và NW. Những tia sáng này bật ra khỏi gương như được mô tả dưới đây:

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 -đại diện cho ánh sáng được hấp thụ. Ánh sáng luôn bị hấp thụ bởi C's hoặc + 's. Điều quan trọng cần lưu ý là đèn chỉ phản chiếu từ gương khi nó chiếm cùng một không gian với gương. Những quy tắc này dễ hiểu hơn nhiều khi bạn vẽ hình phản chiếu ra giấy.

Ví dụ đầu ra

Khi xuất ra, chương trình sẽ in một hình ảnh của căn phòng được chiếu sáng, với các điểm tối được viết dưới dạng @, các điểm sáng để trống và gương không bị ảnh hưởng. Đối với ví dụ trên, đầu ra sẽ là:

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

Điều này có nghĩa là, nếu bạn rút ra các chùm ánh sáng, chúng sẽ không bao giờ chạm tới các khoảng trống được đánh dấu @.

Thêm ví dụ

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

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

Trong ví dụ của bạn, không nên là góc dưới bên trái @?
Peter Taylor

1
@Peter Taylor: Tia SW chạm vào điểm đó.
Briguy37

3
Mang một số điểm tương đồng với thử thách Lasers được đón nhận rất nhiều trên Stack Overflow . Đủ các điểm tương đồng để làm cho các phương thức được sử dụng trong đó thú vị với đủ sự khác biệt để đòi hỏi một số suy nghĩ đáng kể về cách chúng có thể được áp dụng.
dmckee --- ex-moderator mèo con

Có thể sử dụng nhiều trường hợp xác nhận.
dmckee --- ex-moderator mèo con

@dmckee Tôi thêm hai ví dụ nữa.
PhiNotPi

Câu trả lời:


2

Python, 292 ký tự

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,

Đọc trong phòng, làm cho nó hình chữ nhật, sau đó đi ra từ ngọn nến theo mọi hướng. M chứa các ký tự nhân bản hoạt động và hiệu ứng của chúng ( /\cho các hướng hồng y, |-cho các hướng khác)

Có thể xử lý các phòng rộng tới 97 ký tự.


2

c - 504

Dựa vào ngữ nghĩa gọi hàm K & R mặc định. Thực hiện rất thẳng về phía trước ngoại trừ các công cụ fiddle với các tia nảy.

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

Ung dung

//#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');
  }
}

Thẩm định

$ gcc -g -o candle candle_golfed.c
$ for f in candle_room*; do (./candle < $f) ; done
+------+
|  C   |
|@   @ +--+
| @\      |
+---------+
+------+
|  C   |
|@   @ +--+
|  /@ @ @ |
+---------+
+------+
| @/   |
|@   @ +--+
|  C      |
+---------+
+------+
|  \@ @|
|@   @ +--+
|  C      |
+---------+
+-----+
| @ @ |
|@   @|
|  C  |
|@   @|
| @ @ |
+-----+
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.