Znajdziesz się na szachownicy, tak jak się to robi. Możesz zobaczyć wyjście, ale jest okropnie daleko i wolisz nie iść całą drogę. Na szczęście niektórzy miejscowi zaoferowali ci przejażdżkę. Rycerz, Wieża, Biskup i Król chętnie zabiorą cię do miejsca docelowego, ale widząc, jak to jest szachownica, muszą przestrzegać zasad szachowych w drodze do miejsca docelowego. Chcesz się stąd jak najszybciej wydostać, czyją ofertę akceptujesz?
Zadanie
Biorąc pod uwagę dowolnie ukształtowaną i wielkości szachownicę oraz dwa punkty na szachownicy, wyjmij pionek szachowy, który może przemieszczać się między dwoma miejscami w jak najmniejszej liczbie ruchów. Tablice niekoniecznie muszą być ciągłe, co oznacza, że mogą występować przerwy między sekcjami planszy. Każdy z czterech elementów (król, wieża, rycerz i biskup) może poruszać się zgodnie z ich standardowymi zasadami w szachach. Królowa i pionki zostały celowo wykluczone z tego wyzwania.
I / O
Możesz przyjmować dane wejściowe w dowolnym rozsądnym formacie, a także dane wyjściowe w dowolnym wybranym przez siebie formacie. Twoje dane wejściowe i wyjściowe muszą być spójne. Jeśli wiele elementów może dotrzeć do celu w tej samej liczbie ruchów, musisz wydać wszystkie elementy, które mogą się tam dostać w jak najkrótszym czasie. Jeśli żaden z czterech elementów nie dotrze do końca, możesz wydać cokolwiek, o ile różni się ono od wszystkich innych możliwych wyników. Może to obejmować nie wysyłanie niczego lub zgłaszanie błędu.
Przypadki testowe
Kwadrat wskazuje punkt początkowy, a okrąg wskazuje punkt końcowy.
Biskup
Rycerz
Król
Wieża
Król, rycerz
Żaden
Odpowiedzi:
Haskell ,
447439437432 bajtówZadzwoń za pomocą
g <board> <start> <end>
gdzie<board> :: [(Int, Int)]
,<start> :: (Int, Int)
i<end> :: (Int, Int)
. Zwraca listę zawierającą1
dla Rycerza,2
Wieży,3
Biskupa i4
Króla. Jeśli nie zostaną znalezione żadne rozwiązania, konsekwentnie przepełnia stos (co jest liczone jako zgłaszanie błędu, prawda?).Inspiracja pochodzi z rozdziałów LYAH w sprawie Monads-
(%)
tylko uogólnione i grałeminMany
z(&)
odpowiednikiem(Control.Monad.<=<)
. Wszystko inne powinno być mniej lub bardziej oczywiste.Prawdopodobnie można grać w golfa o wiele więcej, ale na razie miałem dość zabawy.
Nie golfowany:
źródło
Mathematica,
326325 bajtówDzięki masterX224 za wskazanie oszczędności bajtów!
Definiuje funkcję
f
przyjmującą trzy argumenty:g
jest listą uporządkowanych par liczb całkowitych reprezentujących tablicęw
orazx
uporządkowanych par reprezentujących kwadraty początkowy i końcowy. Wyjściem jest podzbiór{b, k, n, r}
(reprezentujący odpowiednio biskupa, króla, rycerza i wieżę), które mają ścieżkę minimalnego ruchu między dwoma kwadratami. Na przykład trzeci przypadek testowy jest wywoływany przezf[{{0, 0}, {1, 1}, {1, 2}, {0, 3}}, {0, 0}, {0, 3}]
i zwraca{k}
; dwa ostatnie przypadki testowe wrócić{k, n}
i{}
odpowiednio.Strategią jest przełożenie kwadratów planszy na wierzchołki wykresu, gdzie krawędzie są określane przez ruchy każdego elementu, a następnie użycie wbudowanych procedur graficznych.
Bardziej przyjazna dla użytkownika wersja kodu:
W linii 3
Select[g~Tuples~2, # - #2 & @@ # == d
znajduje wszystkie uporządkowane pary wierzchołków, których różnicą jest wektord
;e
następnie przekształca każdą taką uporządkowaną parę w niekierowaną krawędź wykresu. Tak więca
jest funkcja, która tworzy krawędzie między wszystkimi wierzchołkami, które różnią się stałym wektorem.To wystarcza do zdefiniowania, w linii 4 i 5, wykres króla
y@k
(co ma związek krawędzi uzyskanych przez wektory{1, 1}
,{-1, 1}
,{0, 1}
i{-1, 0}
) oraz wykresu rycerskiejy@n
(która ma to samo z{1, 2}
,{2, 1}
,{-2, 1}
i{-1, 2}
).W linii 7
ConnectedComponents@a@#
pobiera jeden z tych sąsiednich wykresów, a następnie wyszukuje połączone elementy; odpowiada to zgrupowaniu wszystkich segmentów linii wierzchołków w danym kierunku (tak, aby wieża lub biskup nie musieli się przez nie przemieszczać jeden po drugim). Następniee@t@#
w linii 6 umieszcza krawędzie między każdą parą wierzchołków w tym samym połączonym składniku, które są następnieFlatten
edytowane w pojedynczy wykres. Zatem linie od 6 do 8 definiują wykres wieży i wykresy@r
biskupay@b
.Wreszcie linie od 9 do 11 wybierają elementy,
{b, k, n, r}
które dają najkrótszą ścieżkę między dwoma docelowymi wierzchołkami.FindShortestPath
wyrzuci błąd i zwróci nieoceniony, jeśli wierzchołek docelowy nie pojawi się na wykresie (co się stanie, jeśli z niego nie wyprowadzą się żadne krawędzie), więc zamiast tego używamyh@__ -> 0
powrotu0
. Brak ścieżki między prawidłowymi wierzchołkami zwraca listę długości0
, więcMin[z~Complement~{0}]
oblicza długość najmniejszej ścieżki, która faktycznie istnieje, ignorując powyższe niepoprawne przypadki.źródło
f
w tej sesji, ale powinienem to zmienić przed przesłaniem!