Mathematica, 326 325 bayt
Bayt tasarrufuna işaret eden masterX224'e teşekkürler!
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}]]);
Bir işlev tanımlar f
üç argüman alıyor: g
tahtası temsil sayının emretti çiftlerinin bir listesi ve w
ve x
başlangıç ve bitiş kareleri temsil eden çiftleri emretti. Çıktı, {b, k, n, r}
iki kare arasında minimum hareket yoluna sahip olan (sırasıyla, fil, kral, şövalye ve kale temsil eder) alt kümesidir . Örneğin, üçüncü sınama durumu tarafından çağrılır f[{{0, 0}, {1, 1}, {1, 2}, {0, 3}}, {0, 0}, {0, 3}]
ve döndürülür {k}
; Son iki test durumları dönmek {k, n}
ve {}
sırasıyla.
Strateji, tahtanın karelerini, kenarların her bir parçanın hareketleri tarafından belirlendiği bir grafiğin köşelerine dönüştürmek ve daha sonra yerleşik grafik rutinlerini kullanmaktır.
Kodun daha kullanıcı dostu sürümü:
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. satırda Select[g~Tuples~2, # - #2 & @@ # == d
, farkı vektör olan tüm sıralı köşe çiftlerini bulur d
; e
sonra sıralanan her bir çifti yönlendirilmemiş bir grafik kenarına dönüştürür. Öyleyse a
, sabit bir vektöre göre farklılık gösteren tüm köşeler arasında kenarlar oluşturan bir işlevdir.
Bu hatlar 4 ve 5, kral grafik olarak tanımlamak için yeterli y@k
(vektörler tarafından üretilen kenarlarının bütünlüğü alır {1, 1}
, {-1, 1}
, {0, 1}
ve {-1, 0}
) ve şövalye grafik y@n
(aynı yapar ki {1, 2}
, {2, 1}
, {-2, 1}
ve {-1, 2}
).
7. satırda ConnectedComponents@a@#
, bu komşu grafiklerden birini alır ve sonra bağlı bileşenlerini bulur; bu, köşelerin tüm çizgi parçalarını verilen yönde gruplandırmaya karşılık gelir (böylece bir kale veya fil, birer birer hareket etmek zorunda kalmazlar). Daha sonra e@t@#
6. satırda, aynı bağlı bileşendeki her bir köşe çifti arasına kenarlar yerleştirilir ve bunlar daha sonra Flatten
tek bir grafiğe dönüştürülür. Böylece 6 ila 8 arasındaki çizgiler kalenin grafiğini y@r
ve filin grafiğini tanımlar y@b
.
Son olarak, 9 ila 11 arasındaki satırlar {b, k, n, r}
, iki hedef köşesi arasındaki en kısa yolu veren unsurlarını seçer . FindShortestPath
Bir hata atacak ve grafikte bir hedef tepe noktası görünmüyorsa değerlenmemiş olarak geri dönecektir (bu, kenarlardan çıkmazsa gerçekleşecektir), bu nedenle bunun yerine h@__ -> 0
geri dönmek 0
için kullanırız. Ve geçerli köşeler arasındaki bir yolun olmayışı bir uzunluk listesi döndürür 0
, bu nedenle Min[z~Complement~{0}]
yukarıdaki kötü durumları göz ardı ederek mevcut olan en küçük yolun uzunluğunu hesaplar.