อย่า แม้ กะพริบตา


50

ป้อนคำอธิบายรูปภาพที่นี่

ชีวิตของคุณขึ้นอยู่กับสิ่งนี้ อย่ากระพริบตา อย่ากระพริบตา กระพริบตาและคุณจะตาย พวกมันเร็ว เร็วกว่าที่คุณเชื่อ อย่าหันหลังกลับอย่าหันหลังและอย่ากระพริบตา! โชคดี.

Weeping Angelsเป็นเผ่าพันธุ์มนุษย์ต่างดาวที่ไม่สามารถเคลื่อนไหวได้ในขณะที่ถูกคนอื่นมองเห็น (แม้แต่นางฟ้าอีกคน) พวกเขาให้อาหารโดยส่งเหยื่อกลับมาทันเวลา คุณ ( หมอ ) ติดอยู่ในห้องพร้อมกับบางคนและคุณต้องไปที่ควานหาของคุณ


งาน

เขียนโปรแกรมที่จะให้ตัวแทน ASCII ของห้องรูปสี่เหลี่ยมผืนผ้าออกเส้นทางที่จะนำคุณไปสู่ความปลอดภัย หากทูตสวรรค์คนใดสามารถโจมตีได้ตลอดเวลาในระหว่างการดำเนินการของคุณเส้นทางนั้นจะไม่ปลอดภัย ทูตสวรรค์สามารถโจมตีได้หากสามารถมองเห็นคุณในขณะที่ไม่ได้เห็นคุณหรือทูตสวรรค์คนอื่น

อินพุต

อินพุตเป็นสองส่วน ก่อนอื่นทิศทางที่คุณกำลังเผชิญ (NSEW) จากนั้นในบรรทัดที่ประสบความสำเร็จเป็นตัวแทนของห้องแสดงสถานที่เริ่มต้น / สิ้นสุดและสถานที่ / หันหน้าไปทางของเทวดาทั้งหมด

ตัวอย่างด้านล่างแสดงว่ามีทูตสวรรค์องค์หนึ่งหันหน้าไปทางทิศตะวันตกและคุณเริ่มหันหน้าไปทางทิศใต้

S
..........
....D.....
..........
..........
..........
..........
..........
..........
.........W
..........
...T......
  • . - พื้นที่ว่าง
  • D - The Doctor (ตำแหน่งเริ่มต้น)
  • T - ควานหา (ตำแหน่งสุดท้าย)
  • N,S,E,W - ทูตสวรรค์หันหน้าไปทางทิศทางที่ระบุ (เหนือ, ใต้, ตะวันออก, ตะวันตก)

แนวสายตา

คุณสามารถเห็นพื้นที่ใด ๆ ที่มี 45 องศาของทิศทางที่คุณหันหน้าไป แนวสายตาถูกบดบังหากมีเอนทิตี้อื่นตามแนวนอนแนวตั้งหรือแนวทแยง 45 องศา เส้นทแยงมุมอื่น ๆไม่ขัดขวางมุมมอง สายตาของทูตสวรรค์ทำงานในลักษณะเดียวกัน ตัวอย่างเช่นในตัวอย่างต่อไปนี้-แสดงถึงมุมมองของคุณโดยสมมติว่าคุณหันหน้าไปทางทิศใต้

........
...D....
..---...
.-----..
-------.
---N----
---.--N-
---.----

เอาท์พุต

เอาท์พุทเป็นสตริงที่เป็นตัวแทนของเส้นทางที่คุณจะใช้เพื่อออก หากมีเส้นทางที่ปลอดภัยหลายเส้นทางให้เลือกเส้นทางใดเส้นทางหนึ่ง 0หากไม่มีเส้นทางที่มีความปลอดภัยและการส่งออก หากแผนที่ผิดรูปแบบให้ทำตามที่คุณต้องการรวมถึงการขัดข้อง พิจารณาว่าผิดรูปแบบหากห้องไม่ได้เป็นรูปสี่เหลี่ยมผืนผ้าไม่มีทางออก ฯลฯ หากไม่มีเทวดามันไม่ผิดรูปแบบง่าย ๆ

สำหรับแต่ละขั้นตอนคุณสามารถทำหนึ่งในสองสิ่งนี้: เลื่อนไปในทิศทาง NSEW หรือเปลี่ยนเป็นทิศทาง NSEW (โดยไม่เปลี่ยนตำแหน่ง) หากต้องการย้ายเพียงแค่ออกตัวอักษรสำหรับทิศทางนั้น หากต้องการหันไปทางทิศทางให้ออกFตามด้วยตัวอักษรที่เหมาะสม ตัวอย่างเช่นผลลัพธ์ต่อไปนี้:

SSFESSSSSSSW

เป็นเส้นทางที่ปลอดภัยสำหรับตัวอย่างที่กำหนดในส่วนอินพุต คุณเคลื่อนตัวไปทางทิศใต้สองครั้งหันหน้าไปทางทิศตะวันออกเพื่อรักษาทูตสวรรค์ไว้ในสายตาจากนั้นเลื่อนไปทางใต้อีกเจ็ดครั้งและตะวันตกหนึ่งครั้งเพื่อเข้าสู่ควานหา

กรณีทดสอบ

1) คุณสามารถไปรอบ ๆ เทวดาหันหน้าไปทางทิศตะวันออกเพื่อไปที่ควานหา หากคุณไม่ก้าวเข้าหากันโดยตรงพวกเขาจะขังกันและกันดังนั้นมันไม่สำคัญว่าคุณจะหันไปทางไหน

W
...D....
........
........
........
.E.....W
........
........
...T....

2) คุณแพ้ ไม่มีทางที่จะผ่านมันไปได้ พวกเขาสามารถมองเห็นซึ่งกันและกันจนกว่าคุณจะก้าวไปมาระหว่างพวกเขา ณ จุดนี้คุณไม่สามารถเผชิญหน้ากับพวกเขาทั้งสองและคุณเสร็จแล้ว อาจจะเพียงแค่ปิดตาของคุณและได้รับมันด้วย

S
...D....
........
........
........
E......W
........
........
...T....

การชนะ

กฎกอล์ฟมาตรฐานและช่องโหว่ใช้บังคับชนะอย่างน้อยไบต์ ฉันจะพยายามหากรณีทดสอบเพิ่มเติมในไม่ช้า แต่อย่าลังเลที่จะแนะนำตัวคุณเองในระหว่างนี้

รูปภาพและข้อความอ้างอิงจาก Doctor Who


เราสามารถใช้ห้องสมุดเพื่อค้นหาเส้นทางผ่านกราฟได้หรือไม่?
Sparr

@Sparr ใช่ แต่สิ่งที่จำเป็นในการโหลด / รวมไลบรารี่ควรเพิ่มเข้าไปในจำนวนไบต์
Geobits

2
เห็นได้ชัดว่าใช้หุ่นยนต์กระแสน้ำวน!
หมอ

4
@TheDoctor Jack ได้พาเขาไปกับเขาและคุณจะเห็นว่าเขาไม่ได้อยู่ในแผนที่ใด ๆ ( J)
Geobits

1
@Timmy คำจำกัดความมาตรฐานใด ๆสามารถใช้ได้
Geobits

คำตอบ:


6

Python - 559 565 644 633

M=input()
I=1j
Q={"S":I,"N":-I,"E":1,"W":-1}
A=[]
e=enumerate
for y,l in e(M[2:].split()):
 for x,c in e(l):
    P=x+y*1j
    if c=="D":D=(P,Q[M[0]])
    elif c=="T":T=P
    elif c!=".":A+=[(P,Q[c])]
def s(D,h,r=[]):
 def L(X,p,d):
    S=[p+d*(i+j*I)for i in range(x+y)for j in range(-i+1,i)if j]
    for f in[1,1+I,1-I]:
     i=0
     while i<x+y>1>(S[-1]in[a[0]for a in[D]+A]+[T])*i:i+=1;S+=[p+i*f*d]
    return X[0]in S
 if y>=D[0].imag>=(D[0]in[a[0]for a in A])<all(any(L(a,*b)for b in[D]+A)for a in A if L(D,*a))>(D in r)<=D[0].real<=x:
    r+=[D]
    if D[0]==T:print h;exit()
    for n in"SWEN":s((D[0]+Q[n],D[1]),h+n,r);s((D[0],Q[n]),h+"F"+n,r)
s(D,"")
print"0"

ต้องป้อนข้อมูลดังนี้:

"W\n...D....\n........\n........\n........\nE......W\n........\n........\n...T....\n"

โดยพื้นฐานแล้ววิธีการนี้ใช้กับการค้นหาทุกสถานะ (ตำแหน่งและทิศทาง) ที่หมอสามารถเข้าถึงได้อย่างปลอดภัยจัดเก็บวิธีที่เขาไปถึงที่นั่นและพิมพ์วิธีการในกรณีที่ประสบความสำเร็จ ตำแหน่งและทิศทางจะถูกรับรู้ด้วยตัวเลขที่ซับซ้อน

ฉันอาจจะปลอดภัยบางตัวอักษรโดยใช้เลขคณิตจำนวนเชิงซ้อนของ Sage แต่นั่นจะใช้เวลานานมาก

ครั้งแรกที่ฉันคิดว่าฉันสามารถบันทึกตัวละครหกตัวด้วยการให้หมอเปลี่ยนไปในทิศทางที่เฉพาะเจาะจงหลังจากไปถึง Tardis แต่ฉันรู้ว่านี่อาจส่งผลให้เกิดการแก้ปัญหาที่ไม่ถูกต้อง นอกจากนี้ฉันแรกผิดกฎ

นี่คือเวอร์ชันที่ไม่ได้รับการอวดดีเป็นส่วนใหญ่:

Map = input()

I = 1j
string_to_dir = {"S":I,"N":-I,"E":1,"W":-1}

Angels = []
Pos = 0
direction = string_to_dir[Map[0]]
for y,line in enumerate(Map[2:].split()):
    for x,char in enumerate(line):
        Pos = x+y*1j
        if char == "D":
            Doctor = (Pos, direction)
        elif char == "T":
            Tardis = (Pos, direction)
        elif char != ".":
            Angels += [(Pos,string_to_dir[char])]

reachables = []

def display(LoS, Doctor):
    string = ""
    for y,line in enumerate(Map[2:].split()):
        for x,char in enumerate(line):
            if x+y*1j == Doctor[0]:
                string += "D"
            elif x+y*1j in LoS:
                if char in ".D":
                    string += "*"
                else:
                    string += "X"
            elif char != "D":
                string += char
            else:
                string += "."

        string += "\n"
    print string

def LoS(angel,Doctor):
    p,d = angel
    Sight = []
    for i in range(x+y):
        for j in set(range(-i+1,i))-{0}:
            Sight += [p+d*i+d*j*I]
    for line in [d, (1+I)*d, (1-I)*d]:
        for i in range(1,x+y):
            Pos = p + i*line
            Sight += [Pos]
            if Pos in [angel[0] for angel in Angels+[Doctor, Tardis]]:
                break
    return Sight

def search(Doctor, history):
    global reachables

    Sight = sum([LoS(angel, Doctor) for angel in [Doctor]+Angels],[])

    if (
                all(angel[0] in Sight for angel in Angels if Doctor[0] in LoS(angel, Doctor))
            and not (Doctor in reachables)
            and (0<=Doctor[0].imag<=y)
            and (0<=Doctor[0].real<=x)
            and (Doctor[0] not in [angel[0] for angel in Angels])
        ):

        reachables += [Doctor]

        if Doctor[0] == Tardis[0]:
            print history
            exit()
        for new_direction in "SWEN":
            search((Doctor[0]+string_to_dir[new_direction], Doctor[1]), history + new_direction)
            search((Doctor[0], string_to_dir[new_direction]), history + "F" + new_direction)

search(Doctor, "")
print "0"

กรณีทดสอบ

กรณีทดสอบ 1:

SSSFSWWWSSSSFWEFSEFWE

กรณีทดสอบ 2:

0

กรณีทดสอบของ VisualMelon:

SSFWSSSSSFSWWSSWWWFWEEEEFSEFWEFSE

1
ฉันไม่ได้ทดสอบโค้ดของคุณ แต่ดูเหมือนว่าคุณได้วางเอาต์พุตสำหรับกรณีทดสอบ 1 สองครั้ง! นอกจากนี้ฉันยังสนใจที่จะดูว่าโปรแกรมของคุณผลิตอะไรถ้าคุณให้ฟีดมันเป็นกรณีทดสอบที่เสนอ
VisualMelon

@VisualMelon: ขอบคุณสำหรับการจำและฉันรวมกรณีทดสอบ
Wrzlprmft

10

C # 1771 2034 1962 1887 1347 ไบต์

เขียนการตรวจสอบ LOS ที่บล็อกอีกครั้งใน 1 ลูปทำให้เป็นระเบียบมากขึ้นและสั้นลงประมาณ 450bytes

using C=System.Console;using T=System.Math;struct P{int x,y,d;static void Main(){int v=C.ReadLine()[0],w,h,i,o=0,x=0,y=0,O,E,F,e=46;var R=C.In.ReadToEnd().Replace("\r","");var M=new int[w=R.IndexOf("\n"),h=(R.Length+1)/(w+1)];for(;o<h;o++)for(i=0;i<w;i++)if((M[i,o]=R[o+o*w+i])==68)M[x=i,y=o]=e;System.Func<int,int,int,bool>S=null;S=(X,Y,D)=>{var Z="SSSE_WNNNE_W___E_W";int I=0,H=0,L=0,J=Y,K=M[X,Y],B;M[X,Y]=D>0?D:K;for(H=0;H<9;H++)for(I=X,J=Y;H!=4&(I+=H%3-1)<w&I>=0&(J+=H/3-1)<h&&J>=0;){if(((B=M[I,J])==Z[H]|B==Z[H+9])&(D<1||!S(I,J,0)))goto W;if(B!=e)break;}for(B=I=-1;++I<w;B=1)for(J=0;J<h;J++)if(I!=X&J!=Y&(((B=M[I,J])==87&I>X&(H=T.Abs(J-Y))<I-X)|(B==69&I<X&H<X-I)|(B==78&J>Y&(L=T.Abs(I-X))<J-Y)|(B==83&J<Y&L<Y-J))&(D<1||!S(I,J,0)))goto W;W:M[X,Y]=K;return B>1;};P a,p=new P{x=x,y=y,d=v};var A=new System.Collections.Generic.List<P>();System.Action q=()=>{if(((E=M[p.x,p.y])==e|E==84)&!A.Contains(p)&!S(p.x,p.y,p.d))A.Add(p);};q();for(o=0;(O=A.Count)!=o;o=O)for(i=O;i-->o;){p=A[i];if((E=M[p.x,p.y])==84)for(R="";;p=a){i=0;n:a=A[i++];O=T.Abs(p.y-a.y)+T.Abs(a.x-p.x);if(O==1&p.d==a.d)R=(a.y-p.y==1?"N":p.y-a.y==1?"S":a.x-p.x==1?"W":"E")+R;else if(O<1)R="F"+(char)p.d+R;else goto n;if(i<2)goto Z;}if(E==e){if(p.x-->0)q();p.x+=2;if(p.x<w)q();p.x--;if(p.y-->0)q();p.y+=2;if(p.y<h)q();p.y--;for(F=0;F<4;q())p.d="NESW"[F++];}}R="0";Z:C.WriteLine(R);}}

นี่เป็นโปรแกรมที่สมบูรณ์ที่คาดว่าอินพุตจะถูกยกเลิกด้วย EOF และถูกส่งผ่านไปยัง STDIN มัน (หวังว่า) พิมพ์เส้นทางที่สั้นที่สุดไปที่ควานหาหรือ "0" หากไม่มีเส้นทาง มันใช้การค้นหาแรกที่มีความกว้างต่ำเพื่อติดตามเส้นทางที่เป็นไปได้ทั้งหมดจากนั้นจะย้อนรอยย้อนกลับจากควานหาไปยังหมอ

รหัสที่จัดรูปแบบ:

using C=System.Console;
using T=System.Math;

struct P
{
    int x,y,d;

    static void Main()
    {
        int v=C.ReadLine()[0],w,h,i,o=0,x=0,y=0,O,E,F,e=46;
        var R=C.In.ReadToEnd().Replace("\r","");
        var M=new int[w=R.IndexOf("\n"),h=(R.Length+1)/(w+1)];

        for(;o<h;o++)
            for(i=0;i<w;i++)
                if((M[i,o]=R[o+o*w+i])==68)
                    M[x=i,y=o]=e;

        System.Func<int,int,int,bool>S=null;
        S=(X,Y,D)=>
        {
            var Z="SSSE_WNNNE_W___E_W";

            int I=0,H=0,L=0,J=Y,K=M[X,Y],B;
            M[X,Y]=D>0?D:K;

            for(H=0;H<9;H++)
                for(I=X,J=Y;H!=4&(I+=H%3-1)<w&I>=0&(J+=H/3-1)<h&&J>=0;)
                {
                    if(((B=M[I,J])==Z[H]|B==Z[H+9])&(D<1||!S(I,J,0)))
                        goto W;
                    if(B!=e)
                        break;
                }

            for(B=I=-1;++I<w;B=1)
                for(J=0;J<h;J++)
                    if(I!=X&J!=Y&(((B=M[I,J])==87&I>X&(H=T.Abs(J-Y))<I-X)|(B==69&I<X&H<X-I)|(B==78&J>Y&(L=T.Abs(I-X))<J-Y)|(B==83&J<Y&L<Y-J))&(D<1||!S(I,J,0)))
                        goto W;
        W:
            M[X,Y]=K;
            return B>1;
        };

        P a,p=new P{x=x,y=y,d=v};
        var A=new System.Collections.Generic.List<P>();
        System.Action q=()=>{if(((E=M[p.x,p.y])==e|E==84)&!A.Contains(p)&!S(p.x,p.y,p.d))A.Add(p);};
        q();

        for(o=0;(O=A.Count)!=o;o=O)
            for(i=O;i-->o;)
            {
                p=A[i];
                if((E=M[p.x,p.y])==84)
                    for(R="";;p=a)
                    {
                        i=0;
                    n:
                        a=A[i++];

                        O=T.Abs(p.y-a.y)+T.Abs(a.x-p.x);
                        if(O==1&p.d==a.d)
                            R=(a.y-p.y==1?"N":p.y-a.y==1?"S":a.x-p.x==1?"W":"E")+R;
                        else if(O<1)
                            R="F"+(char)p.d+R;
                        else goto n;

                        if(i<2)
                            goto Z;
                    }
                if(E==e)
                {
                    if(p.x-->0)q();
                    p.x+=2;if(p.x<w)q();p.x--;
                    if(p.y-->0)q();
                    p.y+=2;if(p.y<h)q();p.y--;

                    for(F=0;F<4;q())
                        p.d="NESW"[F++];
                }
            }
        R="0";
    Z:
        C.WriteLine(R);
    }
}

เอาต์พุตสำหรับอินพุตตัวอย่าง

SFESWSSSSSSS

เอาท์พุทสำหรับกรณีทดสอบ 1)

WSWSWSSSESESE

เอาต์พุตสำหรับกรณีทดสอบ 2)

0

ฉันนำเสนอกรณีทดสอบใหม่:

S
..E..DS....
...........
...........
...........
...........
...........
...........
...........
....SSSSS.W
.......T...

โปรแกรมของฉันแสดงผล

SESESESESFNSSSSWW

กรณีทดสอบของ WozzeC 1:

EEEEFWSSSFNWWN

กรณีทดสอบของ WozzeC 2:

FSEEEESFWSSSSWFNWWWNFENNEES

ฉันพลาดโอกาสในการใช้ X = System.Console ไปทั้งหมด ขอบคุณสำหรับสิ่งนั้น :)
WozzeC


ฉันเชื่อว่าแพทย์ถูกโจมตีเมื่อเริ่มต้นด้วยกรณีทดสอบของคุณ: S
WozzeC

@WozzeC ทูตสวรรค์ตะวันตกในตะวันออกเฉียงใต้สามารถมองเห็นทูตสวรรค์ตะวันออกในทิศตะวันตกเฉียงเหนือดังนั้นหมอจึงสามารถหลบหนีได้ แต่ ณ จุดนั้นดูเหมือนว่าโซลูชันของฉันจะไม่สังเกตเห็นว่าแพทย์ถูกโจมตีเมื่อเริ่มต้น ทำไมรหัสนี้ถึงทดสอบได้ยาก!
VisualMelon

1
ขอโทษไม่เป็นไร ฉันพลาดรายละเอียดเล็ก ๆ น้อย ๆ ที่พวกเขาไม่สามารถเคลื่อนไหวได้หากทูตสวรรค์องค์อื่นกำลังดูอยู่
WozzeC

2

C # 1454, 1396, 1373, 1303 1279

class P{static int x,d,y=x=d=55,o=170,X=0,Y=0,u,k=3;static string[,]t=new string[o,o];static int[,]m=new int[o,o];static string e=" NS ETD W      .",q="0";static void Main(string[]s){m[0,1]=m[1,8]=-1;m[0,2]=m[1,4]=1;u=e.IndexOf(s[0][0]);for(;k<s[0].Length;k++){var c=s[0][k];if(c=='D'){X=x;Y=y;}if(c=='\\'){y++;x=d;k++;}else m[y,x++]=e.IndexOf(c);}k=A(X,Y,1);if((k&u)!=0){W(X,Y,k,"");}System.Console.Write(q);}static void W(int x,int y,int h,string s){t[y,x]=s;for(int i=1;i<9;i*=2){int l=y+m[0,i],g=x+m[1,i];if(m[l,g]==5)q=t[l,g]=s+e[i];else if(m[l,g]==15){m[l,g]=6;m[y,x]=15;int n=A(g,l,1),U;for(int j=1;j<9;j*=2){var z=t[l,g]??s;if((n&h&j)!=0&z.Length>=s.Length){U=u;u=j;W(g,l,n,s+((u!=j)?"F"+e[j]:"")+e[i]);u=U;}}m[y,x]=6;m[l,g]=0;}}}static int A(int x,int y,int L){int r=15,a,b,c,f=0,g,h,R,B;for(a=1;a<d-5;a++){g=1;for(b=y-a;b<=y+a;b++)for(c=x-a;c<=x+a;c++){B=m[b,c];R=0;bool W=(c+a-x)%a==0,V=(b+a-y)%a==0,z=W&V;if(B>0&B<9&B!=6&B!=5&g!=16&!((W|V)&(f&g)!=0)){h=R;if(b==y-a){R=1;if(c==x-a){h=4;R=9;}else if(c==x+a){h=8;R=5;}B&=h&2;}else if(b==y+a){R=2;if(c==x-a){h=4;R=10;}else if(c==x+a){h=8;R=6;}B&=h&1;}else if(c==x-a){B&=4;R=8;}else if(c==x+a){B&=8;R=4;}else B=0;if(B!=0){if(L==1&&A(c,b,0)==15)r&=R;if(L==0)return R;}}if(z){if(B<9&B>0&!(c==x&y==b))f|=g;g*=2;}}}return r;}}

ขวา. ดังนั้นฉันจึงตัดสินใจที่จะให้มันไปและเด็กชายใช้เวลาสักครู่ มันสร้างขึ้นส่วนใหญ่ใช้ตัวดำเนินการเชิงตรรกะ

  • ทิศเหนือ = 1 = N
  • ใต้ = 2 = S
  • ตะวันออก = 4 = E
  • ตะวันตก = 8 = W
  • หมอ = 6 = D
  • ควานหา = 5 = T
  • 15 = <- พื้นที่ว่างทั้งหมด

เพื่อหลีกเลี่ยงการตรวจสอบค่า Null ฯลฯ ฉันตัดสินใจใช้ฟิลด์ [MAX_SIZE * 3] * [MAX_SIZE] * 3 และวางบอร์ดเกมใกล้กับศูนย์กลาง

การตรวจสอบลูปจะดำเนินการทั้งภายในและภายนอกจนถึง 50 (MAX_SIZE) ดังนั้นสิ่งนี้:

22222
21112
21D12
21112
22222

เมื่อพบ EWS หรือ N ฉันจะตรวจสอบชิ้นส่วนเดียวกัน หากพบสิ่งใดที่มองไปที่ทูตสวรรค์ (ไม่ใช่แพทย์) พวกเขากลับมา 15 ครั้งเป็นเส้นทางฟรี หากพวกเขาไม่ได้ดูพวกเขากลับมาในลักษณะที่หมอควรเผชิญกับความปลอดภัย ie N จะคืนค่า 2 สำหรับทิศใต้ ยกเว้นว่าเป็น NW หรือ NE ซึ่งในกรณีนี้จะส่งคืน 6 (2 + 4) และ 10 (2 + 8) ตามลำดับ

หากทูตสวรรค์สององค์กำลังเฝ้าดูคุณหมอค่าที่ส่งคืนจากสิ่งเหล่านี้จะเป็น "ANDED" ดังนั้นในตัวอย่างการทดสอบ 2 ข้อผิดพลาด 4 และ 8 จะกลายเป็น 0 หมายความว่าตำแหน่งนั้นไม่ดีและควรหลีกเลี่ยง

รหัสขยาย:

class P
{
    static int x,d,y=x=d=55,o=170,X=0,Y=0,u,k=3;
    static string[,] t = new string[o, o];
    static int[,] m = new int[o, o];
    static string e = " NS ETD W      .", q="0";
    static void Main(string[]s)
    {   
        m[0, 1]=m[1, 8]=-1;
        m[0, 2]=m[1, 4]=1;
        u=e.IndexOf(s[0][0]);
        for (;k<s[0].Length;k++)
        {
            var c = s[0][k];
            if (c == 'D') { X = x; Y = y; }
            if (c == '\\') { y++; x = d; k++; }
            else m[y, x++] = e.IndexOf(c);
        }
        k=A(X,Y,1);
        if ((k&u)!=0)
        {
            W(X, Y, k,"");
        }
        System.Console.Write(q);
    }
    static void W(int x,int y,int h,string s){
        t[y, x] = s;
        for (int i = 1; i < 9; i*=2)
        {
            int l = y+m[0, i], g = x+m[1, i];
            if (m[l, g] == 5)
                q = t[l, g] = s + e[i];
            else if (m[l, g] == 15)
            {
                m[l, g] = 6;
                m[y, x] = 15;
                int n = A(g, l,1),U;
                for (int j = 1; j < 9; j *= 2)
                {
                    var z = t[l, g]??s;
                    if ((n & h & j) != 0 & z.Length>=s.Length)
                    {
                        U = u;
                        u = j;
                        W(g, l, n,s+((u != j) ? "F" + e[j] : "") + e[i]);
                        u = U;
                    }
                }
                m[y, x] = 6;
                m[l, g] = 0;
            }
        }
    }
    static int A(int x, int y,int L)
    {
        int r = 15,a,b,c,f=0,g,h,R,B;
        for (a = 1; a < d - 5; a++)
        {
            g = 1;
            for (b = y - a; b <= y + a; b++)
                for (c = x - a; c <= x + a; c++)
                {
                    B=m[b, c];
                    R=0;
                    bool W=(c+a-x)%a==0,V=(b+a-y)%a==0,z=W&V; 
                    if (B>0&B<9&B!=6&B!=5&g!=16&!((W|V)&(f&g)!=0))
                    {
                        h=R;
                        if (b==y-a)
                        {
                            R=1;
                            if(c==x-a){h=4;R=9;}
                            else if(c==x+a){h=8;R=5;}
                            B&=h&2;
                        }
                        else if (b==y+a)
                        {
                            R=2;
                            if(c==x-a){h=4;R=10;}
                            else if (c==x+a){h=8;R=6;}
                            B&=h&1;
                        }
                        else if(c==x-a){B&=4;R=8;}
                        else if(c==x+a){B&=8;R=4;}
                        else B=0;
                        if (B!=0)
                        {
                            if(L==1&&A(c,b,0)==15)r&=R;
                            if (L==0)return R;
                        }
                    }
                    if (z)
                    {
                        if (B < 9 & B > 0 & !(c==x&y==b))
                           f |= g;
                        g *= 2;
                    }
                }
        }
        return r;
    }
}

ผลการทดสอบ

1 ตัวอย่าง: FNSSSWNNNWSSSWSSSSENNESES

2 ตัวอย่าง: ไม่มีทางออก

ตัวอย่าง VisualMelon: FNSSSSSSSWNNNNNNNWSSSSSSSSSSSEE

กรณีทดสอบของฉัน 1: FSSENEEEFWSSFNSWWN

กรณีทดสอบของฉัน 2: FSEEEESFWSSSSFNWWWWNFENNFSEES

ดังที่เห็นได้ว่าหมอของฉันชอบเดินไปรอบ ๆ เหมือนฉีดเพื่อแสดงให้เห็นว่านางฟ้ามันสนุกแค่ไหนที่จะขยับไปมา ฉันสามารถทำให้ซอฟต์แวร์ค้นหาเส้นทางที่สั้นที่สุด แต่ใช้เวลานานขึ้นและต้องการรหัสเพิ่มเติม

กรณีทดสอบสำหรับพวกคุณ

S
D....
..NE.
.WTS.
.S...

อีกหนึ่ง:

E
D....
WNNN.
...E.
.WTE.
.SSE.
.....

1
รหัส golfed ไม่มีที่ว่างในที่เดียวที่จะหยุดการรวบรวม แต่ด้วยการแก้ไขนั้นฉันจะทำให้คุณนับไบต์เพียง 1,392! การทำงานที่ดีได้รับมันต่ำมากและมันเป็นเกมที่ยุติธรรมอย่างสมบูรณ์แบบสำหรับคุณที่จะใช้using S=System.Console;หรือคุณก็สามารถเอา S ทั้งหมดในรหัสของคุณและบันทึก 6 using Systemไบต์โดย ตอนนี้ฉันจะต้องลองและทำให้วิธีการไร้เดียงสาของฉันลดน้อยลง ... ;)
VisualMelon

1
โอ้พื้นที่ที่ไม่ได้รับฉันควรจะดูแลมัน และแน่นอน S = ... ได้ดำเนินไปเล็กน้อยเมื่อฉันเรียนรู้สิ่งนั้น :)
WozzeC

การทำงานที่ดีจะทำให้จำนวนไบต์ลดลง;)
VisualMelon

ฉันพบรหัสบางอย่างที่ไม่เคยใช้ บวกกับสิ่งที่ไม่จำเป็นเพิ่มเติม
WozzeC
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.