Satranç tahtasından kaç


23

Kendinizi bir satranç tahtasında bulursunuz. Çıkışı görebiliyorsunuz ama çok uzakta ve tamamen yürümeyi tercih etmiyorsunuz. Neyse ki bazı yerliler size bir sürüş teklif etti. Bir şövalye, bir kale, bir piskopos ve bir kral, sizi hedefinize götürmek için isteklidirler, ancak bunun nasıl bir satranç tahtası olduğunu görmeye, her birinin gideceğiniz yere satranç kurallarına uyması gerekir. En kısa sürede buradan çıkmak, kimin teklifini kabul ediyorsunuz?

Görev

Keyfi olarak şekillendirilmiş ve boyutlandırılmış bir satranç tahtası ve satranç tahtasında iki puan verildiğinde, iki konum arasında hareket edebilecek satranç taşını mümkün olduğunca az hareketle çıkar. Kurullar mutlaka sürekli olmayacak, bu da pano bölümleri arasında boşluklar olabileceği anlamına gelmeyecektir. Dört parçanın her biri (Kral, Kale, Şövalye ve Piskopos) satrançta standart kurallarına göre hareket edebilir. Kraliçe ve piyon parçaları bilerek bu zorluğun dışında bırakıldı.

I / O

Herhangi bir makul formatta girdi alabilir ve seçtiğiniz formatta da çıktı alabilirsiniz. Giriş ve çıkışınız tutarlı olmalıdır. Birden fazla parça aynı sayıda hamlede hedefe ulaşabiliyorsa, oraya ulaşabilecek tüm parçaları minimum sürede çıkarmalısınız. Dört parçadan hiçbiri bunu başaramazsa, mümkün olan tüm çıktılardan farklı olduğu sürece herhangi bir şeyi çıkarabilirsiniz. Bu hiçbir şey çıkmamayı veya hata atmayı içerebilir.

Test Kılıfları

Bir kare başlangıç ​​noktasını ve bir daire bitiş noktasını gösterir.


Test 1

piskopos


Test 2

Şövalye


Test 3

kral


Test 4

Kale


5. Test

King, Knight


Test 6

Yok


Güzel. Bu hoşuma gitti ama "keyfi şekil ve boyutta satranç tahtası" tek bir varlık değil mi? Gerçekten 2 ve 6 nolu örneklerin buna nasıl uyduğunu anlamıyorum, sadece şövalyelerin arasına atlayabilecekleri iki ayrı tahta gibi görünüyorlar. Belki bir şeyleri özlüyorumdur?
ElPedro

2
@ElPedro Hala tek bir tahta, sürekli bir tahta değil. Keyfi şeklin bir parçası, levhaların sürekli olamayacak olmasıdır.
Buğday Sihirbazı

Örneğin 3, "kral, kraliçe" olmamalı mı?
Kritixi Lithos

@ Teşekkürler. Bundan emin olduğumdan emin değilim ama şimdi anlıyorum.
ElPedro

2
@KritixiLithos İşleri ilginç kılmak için Kraliçe veya Piyon yoktur.
Buğday Sihirbazı

Yanıtlar:


8

Haskell , 447 439 437 432 bayt

t=[1,2]
p=[(+),(-)]
f=filter
a=abs
(#)=elem
x?y=[min x y..max x y]
f&g=(\x->g x>>=f)
(b!1)(c,r)=f(#b)[(c!d,r#s)|(!)<-p,(#)<-p,d<-t,s<-t,d/=s]
(b!2)(c,r)=f(\(d,s)->(c==d&&all(#b)[(c,z)|z<-r?s])||r==s&&all(#b)[(z,r)|z<-c?d])b
(b!3)(c,r)=f(\(d,s)->a(c-d)==a(r-s)&&all(#b)(zip(c?d)$r?s))b
(b!4)(c,r)=f(\(d,s)->a(c-d)<2&&a(r-s)<2)b
(b%p)n s=[s]>>=foldr(&)(:[])(replicate n$b!p)
g b s e=head$f(not.null)[[p|p<-[1..4],e#(b%p)n s]|n<-[0..]]

Kullanarak Çağrı g <board> <start> <end>nerede <board> :: [(Int, Int)], <start> :: (Int, Int)ve <end> :: (Int, Int). 1Knight, 2Rook, 3Bishop ve 4King için içeren bir liste döndürür . Hiçbir çözüm bulunmazsa, sürekli yığının üzerinden taşar (hata atmak sayılır, değil mi?).

Monads- üzerinde LYAH en bölümlerde alınan İlham (%)sadece genelleştirilmiş ve golfed olduğu inManyile (&)eşdeğerdir (Control.Monad.<=<). Geriye kalan her şey kendinden açıklamalı olmalı.

Bu muhtemelen çok daha fazla golf oynayabilir, ama şimdilik yeterince eğlendim.

Ungolfed:

data Piece = Knight | Rook | Bishop | King deriving (Show)
type Place = (Int, Int)
type Board = [Place]

x `to` y = [min x y..max x y]

f <=< g = (\x -> g x >>= f)

moves
    :: Board    -- available spaces
    -> Piece    -- type of piece
    -> Place    -- starting place
    -> [Place]  -- places available in one move
moves b Knight (c,r) =
    filter (`elem` b) [(c!d, r#s) |
                       (!) <- [(+),(-)], (#) <- [(+),(-)],
                       d <- [1,2], s <- [1,2], d/=s]
moves b Rook   (c,r) =
    filter (\(d,s) -> (c == d && all (`elem` b) [(c,z) | z <- r `to` s])
                    || r == s && all (`elem` b) [(z,r) | z <- c `to` d]) b
moves b Bishop (c,r) =
    filter (\(d,s) -> abs(c-d) == abs(r-s)
                && all (`elem` b) (zip (c `to` d) (r `to` s))) b
moves b King   (c,r) =
    filter (\(d,s) -> abs(c-d) <= 1 && abs(r-s) <= 1) b

canGoIn
    :: Board    -- available spaces
    -> Piece    -- type of piece
    -> Int      -- number of moves
    -> Place    -- starting place
    -> [Place]  -- places available in the specified number of moves
canGoIn b p n s =
    return s >>= foldr (<=<) return (replicate n (moves b p))

quickestPieces
    :: Board    -- available spaces
    -> Place    -- starting place
    -> Place    -- ending place
    -> [Piece]  -- quickest pieces
quickestPieces b s e =
        head $ filter (not.null)
            [[p | p <- [Knight, Rook, Bishop, King], elem e (canGoIn b p n s)] |
                n<-[0..]]

Fonksiyonel programlamanın güzel kullanımı!
Buğday Sihirbazı

5

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: gtahtası temsil sayının emretti çiftlerinin bir listesi ve wve xbaş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; esonra 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 Flattentek bir grafiğe dönüştürülür. Böylece 6 ila 8 arasındaki çizgiler kalenin grafiğini y@rve 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 . FindShortestPathBir 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@__ -> 0geri dönmek 0iç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.


fonksiyon isminde çift f için herhangi bir sebep var mı? ya da bir matematik sınırı mı?
masterX244

oh, haha, hayır bu benim açımdan zihinsel bir sınır :) fÇoktan o oturumda bir oturumum vardı , fakat teslim etmeden önce değiştirmeliydim!
Greg Martin
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.