Sie befinden sich auf einem Schachbrett, wie man es tut. Sie können den Ausgang sehen, aber er ist furchtbar weit weg und Sie möchten lieber nicht den ganzen Weg laufen. Zum Glück haben dir einige Einheimische eine Mitfahrgelegenheit angeboten. Ein Ritter, ein Turm, ein Bischof und ein König sind alle bereit, Sie an Ihr Ziel zu bringen, aber da dies ein Schachbrett ist, müssen sie sich auf dem Weg zu Ihrem Ziel an die Schachregeln halten. Sie möchten so schnell wie möglich hier raus, wessen Angebot nehmen Sie an?
Aufgabe
Wenn Sie ein beliebig geformtes und großes Schachbrett und zwei Punkte auf dem Schachbrett haben, geben Sie die Schachfigur aus, die sich in so wenigen Zügen wie möglich zwischen den beiden Positionen bewegen kann. Boards werden nicht unbedingt durchgehend sein, was bedeutet, dass es Lücken zwischen Abschnitten des Boards geben kann. Jede der vier Figuren (König, Turm, Ritter und Bischof) kann sich nach ihren Standardregeln im Schach bewegen. Die Dame und die Bauern wurden absichtlich aus dieser Herausforderung herausgenommen.
I / O
Sie können Eingaben in jedem vernünftigen Format und Ausgaben in jedem von Ihnen gewählten Format vornehmen. Ihre Eingabe und Ausgabe muss in sich konsistent sein. Wenn mehrere Teile in der gleichen Anzahl von Zügen zum Ziel gelangen können, müssen Sie alle Teile ausgeben, die in kürzester Zeit dort ankommen können. Wenn keines der vier Stücke es bis zum Ende schafft, können Sie etwas ausgeben, solange es sich von allen anderen möglichen Ausgaben unterscheidet. Dies kann das Ausgeben von nichts oder das Auslösen eines Fehlers beinhalten.
Testfälle
Ein Quadrat kennzeichnet den Startpunkt und ein Kreis kennzeichnet den Endpunkt.
Bischof
Ritter
König
Turm
König, Ritter
Keiner
Antworten:
Haskell ,
447439437432 BytesRufen Sie mit
g <board> <start> <end>
dem<board> :: [(Int, Int)]
,<start> :: (Int, Int)
und<end> :: (Int, Int)
. Gibt eine Liste zurück, die1
Ritter,2
Turm,3
Bischof und4
König enthält. Wenn keine Lösungen gefunden werden, läuft der Stapel ständig über (das zählt als Fehlerauslösung, oder?).Inspiration aus Lyah die Kapitel über Monads- genommen
(%)
ist nur eine verallgemeinerte und golfedinMany
, mit(&)
entspricht(Control.Monad.<=<)
. Alles andere sollte mehr oder weniger selbsterklärend sein.Dies kann wahrscheinlich viel mehr Golf gespielt werden, aber ich hatte jetzt genug Spaß.
Ungolfed:
quelle
Mathematica,
326325 BytesVielen Dank an masterX224 für den Hinweis auf eine Byte-Ersparnis!
Definiert eine Funktion
f
mit drei Argumenten:g
ist eine Liste von geordneten Paaren von Ganzzahlen, die die Karte darstellen,w
undx
geordneten Paaren, die die Start- und Endquadrate darstellen. Die Ausgabe ist die Teilmenge von{b, k, n, r}
(die jeweils Bischof, König, Ritter und Turm darstellt), die einen Pfad mit minimalen Bewegungen zwischen den beiden Feldern aufweist. Beispielsweise wird der dritte Testfall von aufgerufenf[{{0, 0}, {1, 1}, {1, 2}, {0, 3}}, {0, 0}, {0, 3}]
und kehrt zurück{k}
. Die letzten beiden Testfälle geben jeweils{k, n}
und{}
zurück.Die Strategie besteht darin, die Quadrate der Tafel in Eckpunkte eines Graphen zu übersetzen, wobei die Kanten durch die Bewegungen der einzelnen Teile bestimmt werden, und dann integrierte Graphenroutinen zu verwenden.
Benutzerfreundlichere Version des Codes:
Select[g~Tuples~2, # - #2 & @@ # == d
Findet in Zeile 3 alle geordneten Knotenpaare, deren Differenz der Vektor istd
;e
transformiert dann jedes dieser geordneten Paare in eine ungerichtete Graphenkante. Diesa
ist eine Funktion, die Kanten zwischen allen Scheitelpunkten erstellt, die sich durch einen festen Vektor unterscheiden.Das reicht zu definieren, in den Zeilen 4 und 5, die Königs Graph
y@k
(die die Vereinigung der Kanten durch die Vektoren erzeugt nimmt{1, 1}
,{-1, 1}
,{0, 1}
, und{-1, 0}
) und der Ritter des Diagrammsy@n
(was tut das gleiche mit{1, 2}
,{2, 1}
,{-2, 1}
, und{-1, 2}
).Nimmt in Zeile 7
ConnectedComponents@a@#
einen dieser Nachbargraphen und findet dann seine verbundenen Komponenten; Dies entspricht einer Gruppierung aller Liniensegmente von Scheitelpunkten in der angegebenen Richtung (damit ein Turm oder Läufer sie nicht einzeln durchlaufen muss). Ine@t@#
Zeile 6 werden dann Kanten zwischen jedes Paar von Scheitelpunkten in derselben verbundenen Komponente eingefügt, die dannFlatten
zu einem einzelnen Diagramm zusammengefasst werden. Somit definieren die Linien 6 bis 8 den Turmgrapheny@r
und den Bischofsgrapheny@b
.Schließlich wählen die Linien 9 bis 11 die Elemente aus
{b, k, n, r}
, die den kürzesten Weg zwischen den beiden Zielscheitelpunkten ergeben.FindShortestPath
wird einen Fehler auslösen und unbewertet zurückgeben, wenn ein Zielscheitelpunkt nicht im Diagramm angezeigt wird (was passiert, wenn keine Kanten von ihm ausgehen). In diesen Fällen verwenden wir stattdessen dieh@__ -> 0
Rückgabe0
. Und das Fehlen eines Pfads zwischen gültigen Scheitelpunkten gibt eine Liste mit Längenangaben zurück0
.Min[z~Complement~{0}]
Berechnet daher die Länge des kleinsten Pfads, der tatsächlich existiert, und ignoriert dabei die oben genannten fehlerhaften Fälle.quelle
f
in dieser Sitzung, aber ich hätte sie vor der Einreichung ändern sollen!