ส่องสว่างห้องมิเรอร์


13

เป้าหมาย

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

ตัวอย่างอินพุต / ห้อง

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

เทียนเป็นตัวแทนที่มีCและผนัง / กระจกจะแสดงด้วย|, -, หรือ/ \ผนังตัวเองเป็นกระจก +มุมของห้องพักที่จะแสดงด้วย

ห้องจะไม่มีผนังแนวทแยงและแสงจะไม่สามารถหลบหนีออกจากห้องได้

นอกจากนี้ตัวละครตัวแรกในบรรทัดจะเป็นส่วนหนึ่งของกำแพงนอกห้องเสมอ ตัวอักษรสุดท้ายแน่นอนในแต่ละบรรทัดจะเป็นผนังฝั่งตรงข้ามของห้อง ไม่มีตัวละครระหว่างสองตัวนี้ที่จะอยู่นอกห้อง

แสงและการสะท้อน

เทียนเปล่งแสงลำแสงแปดทิศทางในทิศทางพื้นฐานแปด: N, S, E, W, NE, SE, SW และ NW รังสีของแสงเหล่านี้กระเด็นออกมาจากกระจกตามที่อธิบายไว้ด้านล่าง:

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 -หมายถึงแสงที่ถูกดูดกลืน แสงถูกดูดซับโดย C's หรือ + เสมอ เป็นสิ่งสำคัญที่จะต้องทราบว่าแสงสะท้อนออกจากกระจกเฉพาะเมื่อมันครอบครองพื้นที่เดียวกับกระจก กฎเหล่านี้ง่ายต่อการเข้าใจเมื่อคุณวาดภาพสะท้อนออกมาบนกระดาษ

ตัวอย่างผลลัพธ์

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

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

@ซึ่งหมายความว่าถ้าคุณดึงออกคานของแสงที่พวกเขาจะไม่เคยไปถึงช่องว่างที่มีเครื่องหมาย

ตัวอย่างเพิ่มเติม

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

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

ในตัวอย่างของคุณมุมซ้ายล่างไม่ควร@ใช่หรือไม่
ปีเตอร์เทย์เลอร์

1
@ Peter Taylor: ลำแสง SW กระทบจุดนั้น
Briguy37

3
หมีคล้ายคลึงกันบางอย่างที่จะได้รับเป็นอย่างดีความท้าทายเลเซอร์บนกองมากเกิน ความคล้ายคลึงกันมากพอที่จะทำให้วิธีการที่ใช้ในนั้นน่าสนใจมีความแตกต่างมากพอที่จะต้องใช้ความคิดอย่างมากเกี่ยวกับวิธีที่อาจนำไปใช้
dmckee --- ผู้ดูแลอดีตแมว

สามารถใช้กรณีการตรวจสอบเพิ่มเติม
dmckee --- ผู้ดูแลอดีตลูกแมว

@dmckee ฉันได้เพิ่มอีกสองตัวอย่าง
PhiNotPi

คำตอบ:


2

Python 292 ตัวอักษร

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,

อ่านในห้องทำให้เป็นรูปสี่เหลี่ยมผืนผ้าแล้วเดินออกมาจากเทียนในทุกทิศทาง M มีอักขระมิรเรอร์ที่แอ็คทีฟและเอฟเฟกต์ ( /\สำหรับทิศทางที่สำคัญ|-สำหรับคนอื่น ๆ )

สามารถจัดการห้องได้กว้างถึง 97 ตัวอักษร


2

c - 504

อาศัยฟังก์ชั่นเริ่มต้นของ K&R ที่เรียกความหมาย การใช้งานไปข้างหน้าอย่างตรงไปตรงมามากยกเว้นเรื่องซอที่มีแสงกระดอน

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

Ungolfed

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

การตรวจสอบ

$ gcc -g -o candle candle_golfed.c
$ for f in candle_room*; do (./candle < $f) ; done
+------+
|  C   |
|@   @ +--+
| @\      |
+---------+
+------+
|  C   |
|@   @ +--+
|  /@ @ @ |
+---------+
+------+
| @/   |
|@   @ +--+
|  C      |
+---------+
+------+
|  \@ @|
|@   @ +--+
|  C      |
+---------+
+-----+
| @ @ |
|@   @|
|  C  |
|@   @|
| @ @ |
+-----+
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.