Mathematica, 326 325 bytes
ขอบคุณ masterX224 สำหรับการชี้ให้เห็นถึงการประหยัดไบต์!
f[g_,w_,x_]:=(c={{1,1},{-1,1}};s=c.c/2;e=#<->#2&@@@#&;j=Join;h=FindShortestPath;t=#~Tuples~2&;a@d_:=e@Select[t@g,#-#2&@@#==d&];y@k=j@@(a/@j[s,c]);y@n=j@@(a/@{{1,2},{2,1},{-2,1},{-1,2}});v=Flatten[e@t@#&/@ConnectedComponents@a@#&/@#]&;y@r=v@s;y@b=v@c;Pick[p={b,k,n,r},z=Length[h[y@#,w,x]/.h@__->0]&/@p,Min[z~Complement~{0}]]);
กำหนดฟังก์ชั่นที่f
ใช้สามข้อโต้แย้ง: g
เป็นรายการของคู่จำนวนเต็มสั่งซื้อตัวแทนคณะกรรมการและw
และx
คู่สั่งซื้อเป็นตัวแทนของสี่เหลี่ยมเริ่มต้นและสิ้นสุด เอาท์พุทเป็นส่วนย่อยของ{b, k, n, r}
(เป็นตัวแทนของบิชอปกษัตริย์อัศวินและโกงตามลำดับ) ซึ่งมีเส้นทางการเคลื่อนไหวน้อยที่สุดระหว่างสองสแควร์ ยกตัวอย่างเช่นกรณีทดสอบที่สามคือการเรียกโดยf[{{0, 0}, {1, 1}, {1, 2}, {0, 3}}, {0, 0}, {0, 3}]
และผลตอบแทน{k}
; กรณีทดสอบทั้งสองกรณีกลับมา{k, n}
และ{}
ตามลำดับ
กลยุทธ์คือการแปลกำลังสองของกระดานเป็นจุดยอดของกราฟโดยที่ขอบถูกกำหนดโดยการเคลื่อนไหวของแต่ละชิ้นจากนั้นใช้การทำกราฟในตัว
รหัสที่เป็นมิตรต่อผู้ใช้มากขึ้น:
1 f[g_, w_, x_] := ( c = {{1, 1}, {-1, 1}}; s = c.c/2;
2 e = # <-> #2 & @@@ # &; j = Join; h = FindShortestPath; t = #~Tuples~2 &;
3 a@d_ := e@Select[t@g, # - #2 & @@ # == d &];
4 y@k = j @@ (a /@ j[s, c]);
5 y@n = j @@ (a /@ {{1, 2}, {2, 1}, {-2, 1}, {-1, 2}});
6 v = Flatten[e@t@# & /@
7 ConnectedComponents@a@# & /@ #] &;
8 y@r = v@s; y@b = v@c;
9 Pick[p = {b, k, n, r},
10 z = Length[h[y@#, w, x] /. h@__ -> 0] & /@ p,
11 Min[z~Complement~{0}]]
12 );
ในบรรทัดที่ 3 Select[g~Tuples~2, # - #2 & @@ # == d
พบคู่สั่งของจุดที่มีความแตกต่างคือเวกเตอร์d
; e
จากนั้นแปลงแต่ละคู่ที่ได้รับคำสั่งดังกล่าวเป็นขอบกราฟที่ไม่ได้บอกทิศทาง ดังนั้นa
เป็นฟังก์ชั่นที่สร้างขอบระหว่างจุดทั้งหมดที่แตกต่างกันโดยเวกเตอร์คงที่
นั่นเพียงพอที่จะกำหนดในสายที่ 4 และ 5 กราฟของกษัตริย์y@k
(ซึ่งจะมีสหภาพของขอบที่สร้างขึ้นโดยพาหะที่{1, 1}
, {-1, 1}
, {0, 1}
และ{-1, 0}
) และกราฟอัศวินy@n
(ซึ่งไม่เหมือนกันกับ{1, 2}
, {2, 1}
, {-2, 1}
และ{-1, 2}
)
ในบรรทัดที่ 7 ConnectedComponents@a@#
ใช้กราฟเพื่อนบ้านตัวใดตัวหนึ่งแล้วพบส่วนประกอบที่เชื่อมต่อ สิ่งนี้สอดคล้องกับการจัดกลุ่มทุกส่วนของจุดยอดในทิศทางที่กำหนด (เพื่อให้ผู้เล่นใหม่หรืออธิการไม่จำเป็นต้องย้ายพวกมันทีละคน) จากนั้นe@t@#
ในบรรทัดที่ 6 จะวางขอบระหว่างจุดยอดทุกคู่ในองค์ประกอบที่เชื่อมต่อเดียวกันซึ่งจะถูกเขียนFlatten
ลงในกราฟเดียว ดังนั้นสายที่ 6 ถึง 8 กำหนดกราฟโกงของกราฟบิชอปy@r
y@b
ในที่สุดบรรทัดที่ 9 ถึง 11 จะเลือกองค์ประกอบของ{b, k, n, r}
เส้นทางที่สั้นที่สุดระหว่างจุดยอดเป้าหมายสองแห่ง FindShortestPath
จะโยนข้อผิดพลาดและคืนค่าที่ไม่ประเมินค่าถ้าจุดยอดเป้าหมายไม่ปรากฏในกราฟ (ซึ่งจะเกิดขึ้นหากไม่มีขอบเกิดจากมัน) ดังนั้นเราจึงใช้h@__ -> 0
เพื่อส่งกลับ0
ในกรณีเหล่านั้นแทน และการขาดเส้นทางระหว่างจุดยอดที่ถูกต้องส่งคืนรายการความยาว0
ดังนั้นMin[z~Complement~{0}]
คำนวณความยาวของเส้นทางที่เล็กที่สุดที่มีอยู่จริงโดยไม่สนใจกรณีที่ไม่ดีข้างต้น