Aynalı Bir Odayı Aydınlatın


13

Hedef

Bu yarışmada, içinde bir mum bulunan rastgele bir oda verilir. Amaç, karanlık noktaları @'s ile değiştirerek odanın hangi bölümlerinin mum tarafından aydınlatılacağını belirleyen en kısa programı (bu golf) yazmaktır . Program, çıktı STDOUT'a yazdırılmış olarak STDIN'den bir oda almalıdır.

Örnek Giriş / Oda

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

Mum ile temsil edilir C, ve duvarlar / ayna ile temsil edilir |, -, /ya da \. Duvarların kendisi aynalardır. Odanın köşeleri a ile temsil edilir +.

Odalarda asla çapraz duvarlar olmayacak ve ışık odadan asla kaçamayacaktır.

Ayrıca, bir satırdaki ilk karakter her zaman odadaki duvarın bir parçası olacaktır. Her satırdaki mutlak son karakter odanın karşı duvarı olacaktır. Bu ikisi arasında hiçbir karakter odanın dışında kalmayacak.

Işık ve Yansıma

Mum sekiz temel yönde sekiz (lazer benzeri) ışık yayar: N, S, E, W, NE, SE, SW ve NW. Bu ışık ışınları aşağıda açıklandığı gibi aynalardan sıçrar:

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 -emilen ışığı temsil eder. Işık her zaman C veya + 'lar tarafından emilir. Işıkların bir aynadan sadece ayna ile aynı alanı işgal ettiğinde yansıdığını belirtmek önemlidir. Yansımayı kağıda çizdiğinizde bu kuralların anlaşılması çok daha kolaydır.

Örnek Çıktı

Çıktı olarak, program aydınlatılmış odanın bir görüntüsünü basmalı, koyu lekeler bir olarak yazılmalı @, açık noktalar boş bırakılmalı ve aynalar etkilenmemelidir. Yukarıdaki örnek için çıktı:

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

Bu, ışık ışınlarını çıkardıysanız, asla işaretli alanlara ulaşmayacakları anlamına gelir @.

Daha fazla örnek

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

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

Örneğinizde, sol alt köşe de @olmamalı mı?
Peter Taylor

1
@Peter Taylor: SW ışını o noktaya çarpıyor.
Briguy37

3
Stack Overflow'da çok iyi karşılanan Lasers yarışmasına bazı benzerlikler taşır . Burada kullanılan yöntemleri ilginç kılmak için yeterince benzerlik, nasıl uygulanabileceği konusunda dikkate değer bir düşünce gerektirmektedir.
dmckee --- eski moderatör kedi yavrusu

Daha fazla doğrulama vakası kullanabilir.
dmckee --- eski moderatör kedi yavrusu

@dmckee İki örnek daha ekledim.
PhiNotPi

Yanıtlar:


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,

Odaya okur, dikdörtgen yapar, daha sonra mumdan her yöne doğru yürür. M aktif ayna karakterlerini ve etkilerini içerir ( /\kardinal yönler |-için, diğerleri için)

97 karakter genişliğe kadar odaları işleyebilir.


2

c - 504

S ve R varsayılan fonksiyon çağrı semantiği dayanır. Işınları sıçrayan keman şeyler dışında çok basit bir uygulama.

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

onaylama

$ gcc -g -o candle candle_golfed.c
$ for f in candle_room*; do (./candle < $f) ; done
+------+
|  C   |
|@   @ +--+
| @\      |
+---------+
+------+
|  C   |
|@   @ +--+
|  /@ @ @ |
+---------+
+------+
| @/   |
|@   @ +--+
|  C      |
+---------+
+------+
|  \@ @|
|@   @ +--+
|  C      |
+---------+
+-----+
| @ @ |
|@   @|
|  C  |
|@   @|
| @ @ |
+-----+
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.