C # - 897 862 ไบต์
พบข้อบกพร่องร้ายแรงด้วยการวางมิเรอร์ในสถานที่ที่ไม่สามารถทำได้ ตอนนี้มันใช้งานได้หวังว่า! นอกจากนี้ยังมีการเล่นกอล์ฟบางเบาไม่สามารถออกจากวงในขณะที่มี ... น่าอับอาย
โปรแกรมที่สมบูรณ์ใช้อินพุตจาก STDIN เอาต์พุตไปยัง STDOUT
มันสนุกมากมันแก้ปัญหาได้ดีด้วยปัญหา 7 คูณ 5 (และเมื่อคุณลบกระจกทำให้มันเป็นไปไม่ได้) ใช้เวลาประมาณ 1 ชั่วโมงเพื่อแก้ปัญหา 30 คูณ 5
using Q=System.Console;class P{static int w,L;static string S(char[]M,int t,int r,int i,int d,int[]B){var s="";if(r<0)return s;M=(char[])M.Clone();B=(int[])B.Clone();B[i]=1;for(i+=d;M[t]<48|t==i;i=t+(d=t<w?w:t>L-w?-w:t%w<1?1:-1))if(++t>=L){for(i=0;++i<L&r>0;)if(B[i]<1&M[i]<33){M[i]='.';r--;}return r<1?new string(M):s;}int c=M[i];if(c>32)s=c>47|c<46?s=c==M[t]?S(M,t,r,t,0,B):s:S(M,t,r,i,c<47?w/d:-w/d,B);else if((s=S(M,t,r,i,d,B))==""&B[i]<1){M[i]='.';s=S(M,t,r-1,i,w/d,B);if(s==""){M[i]='/';s=S(M,t,r-1,i,-w/d,B);}}return s;}static void Main(){string a,A="",R=A;for(;(a=Q.ReadLine())!=null;A+=a)L+=(w=a.Length);var G=A.ToCharArray();int r=0,i=L;for(;i>0;G[i]=G[i]=='|'?',':G[i])if(G[--i]==47|G[i]==92){r++;G[i]=' ';}a=S(G,0,r,1,w,new int[L]);if(a=="")R="Impossible\n";else for(;i<L;i+=w)R+=a.Substring(i,w)+"\n";Q.Write(R.Replace(".","\\").Replace(",","|"));}}
7 จาก 5 ตัวอย่าง:
+abcde+
f/////d
a// c
f |
+-b-e-+
+abcde+
f \ d
a/ //c
f/ \ /|
+-b-e-+
รุ่นที่เป็นไปไม่ได้:
+abcde+
f ////d
a// c
f |
+-b-e-+
Impossible
มีบางสิ่งที่แตกต่างออกไป (โปรแกรมไม่ได้ดูเค้าโครงกระจกต้นฉบับ):
+a----+
|//// |
|/////|
|/////|
+----a+
+a----+
| /\\\|
|\\\\\|
|\\/\\|
+----a+
โซลูชัน 30 จาก 5:
+abcdefghijklmnopqrstuvwxyA-+
| \\\\\\\\\\\\\\\\\\\\\\\\ \|
| / //|
|\ \|
+-Abcdefghijklmnopqrstuvwxya+
มันจะมองหาแหล่งกำเนิดแสงเลเซอร์แต่ละแหล่งและสร้างเส้นทางที่ถูกต้องสำหรับมัน (ถ้าทำได้) จากนั้นเลื่อนไปยังแหล่งถัดไป มันเป็นการค้นหาในเชิงลึกแรก ๆ ที่ค่อนข้างง่ายซึ่งต้องรู้ว่าแหล่งเลเซอร์ (เป้าหมาย) กำลังดูอยู่มีกระจกกี่ตัวที่จะวางเซลล์ปัจจุบันที่เป็น "ที่" ทิศทางที่มันเคลื่อนเข้าและแต่ละเซลล์ มีการเยี่ยมชมแล้ว (เพื่อไม่ให้มีการติดตั้งกระจกอยู่ที่ไหนสักแห่ง) 3 ตัวสุดท้ายใช้สำหรับประกอบเส้นทางสำหรับเป้าหมายปัจจุบันและเมื่อรีเซ็ตเมื่อเป้าหมายเปลี่ยนแปลง เมื่อเลเซอร์ทั้งหมดเชื่อมโยงกันแล้วมันจะดำเนินต่อไปและเติมเต็มช่องว่างใด ๆ ที่ไม่จำเป็นต้องเว้นว่างไว้ (อีกเหตุผลหนึ่งที่ต้องทราบทุกครั้งที่มีการเยี่ยมชม)
เมื่อมันกำลังสร้างเส้นทางมันจะ "ไปข้างหน้า" มากกว่าการใส่กระจกและเมื่อมันทำมันจะใช้กระจก "\" ซึ่งจะเห็นได้ดีที่สุดในตัวอย่าง "สิ่งที่แตกต่าง" ด้านบนซึ่งจะข้ามเซลล์แรกด้านล่าง ด้านบนสุด 'a' จากนั้นเติม "\" อย่างต่อเนื่องหากสามารถหาวิธีแก้ปัญหาด้วยวิธีอื่นหรือ "/" (ตามธรรมชาติถ้าข้ามเซลล์แรกส่งผลให้ไม่สามารถหาวิธีแก้ปัญหาได้ ติดตามย้อนกลับและลองวางกระจกไว้ที่นั่นแทน)
using Q=System.Console;
class P
{
static int w,L;
// M is cur grid
// t is target edge thing (0->L)
// r is mirrors remaining
// i is pos
// d is dir
static string S(char[]M,int t,int r,int i,int d,int[]B)
{
var s="";
if(r<0) // no mirrors left
return s;
// clone everything
M=(char[])M.Clone();
B=(int[])B.Clone();
B[i]=1; // can't write to this
for(i+=d; // move i
M[t]<48|t==i; // only if target is something sensible (increment if i==t)
i=t+(d=t<w?w:t>L-w?-w:t%w<1?1:-1)) // reflect, should be fine for w=3
if(++t>=L) // run off the end
{
for(i=0;++i<L&r>0;) // don't need I any more (count through everything)
if(B[i]<1&M[i]<33) // not been here & it's open space
{
M[i]='.'; // doesn't matter
r--;
}
return r<1?new string(M):s; // none remaining ? victory : defeat
}
int c=M[i];
if(c>32) // not boring
s=c>47|c<46? // hit edge
s=c==M[t]? // hit the correct thing
S(M,t,r,t,0,B): // i+0=t, tells it to increment t
s
:S(M,t,r,i,c<47?w/d:-w/d,B); // mirror
else // boring
if((s=S(M,t,r,i,d,B))==""&B[i]<1) // fwd
{
M[i]='.'; // use . instead of \
s=S(M,t,r-1,i,w/d,B); // \
if(s=="")
{
M[i]='/';
s=S(M,t,r-1,i,-w/d,B); // /
}
}
return s;
}
static void Main()
{
string a,A="",R=A; // R is free
for(;(a=Q.ReadLine())!=null;A+=a) // read input
L+=(w=a.Length); // note width, accumulate length
var G=A.ToCharArray();
int r=0,i=L; // count mirrors (I refuse to make these static)
for(;i>0; // end on i=0
G[i]=G[i]=='|'?',':G[i]) // replace | with ,
if(G[--i]==47|G[i]==92) // remove and count mirrors
{
r++;
G[i]=' '; // storing G[i] doesn't seem to save anything
}
// search
a=S(G,0,r,1,w,new int[L]);
if(a=="") // defeat
R="Impossible\n";
else // victory
for(;i<L;i+=w) // for each line
R+=a.Substring(i,w)+"\n";
Q.Write(R.Replace(".","\\").Replace(",","|")); // swap back | and \
}
}