Vous vous retrouvez sur un échiquier, comme on le fait. Vous pouvez voir la sortie mais elle est terriblement loin et vous préférez ne pas marcher tout le chemin. Heureusement, certains habitants vous ont proposé un tour. Un chevalier, une tour, un évêque et un roi sont tous prêts à vous emmener à votre destination, mais voyant comment c'est un échiquier, ils doivent chacun respecter les règles des échecs sur le chemin de votre destination. Vous souhaitez sortir d'ici le plus tôt possible, quelle offre acceptez-vous?
Tâche
Étant donné un échiquier de forme et de taille arbitraires et deux points sur l'échiquier, sortez la pièce d'échecs qui peut se déplacer entre les deux emplacements en aussi peu de mouvements que possible. Les conseils ne seront pas nécessairement continus, ce qui signifie qu'il pourrait y avoir des écarts entre les sections du conseil. Chacune des quatre pièces (roi, tour, chevalier et évêque) peut se déplacer selon ses règles standard aux échecs. Les pièces de la Reine et du pion ont été intentionnellement exclues de ce défi.
E / S
Vous pouvez prendre des entrées dans n'importe quel format raisonnable et vous pouvez également produire dans n'importe quel format que vous choisissez. Vos entrées et sorties doivent être cohérentes. Si plusieurs pièces peuvent arriver à destination dans le même nombre de coups, vous devez sortir toutes les pièces qui peuvent y arriver en un minimum de temps. Si aucune des quatre pièces ne parvient à la fin, vous pouvez produire n'importe quoi tant qu'il est distinct de toutes les autres sorties possibles. Cela peut inclure la sortie de rien ou le lancement d'une erreur.
Cas de test
Un carré indique le point de départ et un cercle indique le point d'arrivée.
Évêque
Chevalier
Roi
Tour
Roi, chevalier
Aucun
Réponses:
Haskell ,
447439437432 octetsAppel à l' aide
g <board> <start> <end>
où<board> :: [(Int, Int)]
,<start> :: (Int, Int)
et<end> :: (Int, Int)
. Renvoie une liste contenant1
Knight,2
Rook,3
Bishop et4
King. Si aucune solution n'est trouvée, elle déborde systématiquement la pile (cela compte comme une erreur, non?).L'inspiration tirée des chapitres de LYAH sur les monades -
(%)
est juste un généralisé et golféinMany
, avec l'(&)
équivalent de(Control.Monad.<=<)
. Tout le reste devrait être plus ou moins explicite.Cela peut probablement être joué beaucoup plus, mais je me suis assez amusé pour l'instant.
Non golfé:
la source
Mathematica,
326325 octetsMerci à masterX224 pour avoir souligné une économie d'octets!
Définit une fonction
f
prenant trois arguments:g
est une liste de paires ordonnées d'entiers représentant la carte etw
et dex
paires ordonnées représentant les carrés de début et de fin. La sortie est le sous-ensemble de{b, k, n, r}
(représentant l'évêque, le roi, le chevalier et la tour, respectivement) qui a un chemin de mouvements minimaux entre les deux carrés. Par exemple, le troisième cas de test est invoqué parf[{{0, 0}, {1, 1}, {1, 2}, {0, 3}}, {0, 0}, {0, 3}]
et retourne{k}
; les deux derniers cas de test renvoient{k, n}
et{}
, respectivement.La stratégie consiste à traduire les carrés de la planche en sommets d'un graphique, où les bords sont déterminés par les mouvements de chaque pièce, puis à utiliser des routines graphiques intégrées.
Version plus conviviale du code:
À la ligne 3,
Select[g~Tuples~2, # - #2 & @@ # == d
trouve toutes les paires de sommets ordonnés dont la différence est le vecteurd
;e
transforme ensuite chacune de ces paires ordonnées en un bord de graphe non orienté. Il ena
va de même pour une fonction qui crée des arêtes entre tous les sommets qui diffèrent par un vecteur fixe.Cela suffit à définir, dans les lignes 4 et 5, le graphe du roi
y@k
(qui prend l'union des bords générés par les vecteurs{1, 1}
,{-1, 1}
,{0, 1}
et{-1, 0}
) et le graphique du chevaliery@n
(qui fait la même chose avec{1, 2}
,{2, 1}
,{-2, 1}
et{-1, 2}
).À la ligne 7,
ConnectedComponents@a@#
prend l'un de ces graphiques voisins et trouve ensuite ses composants connectés; cela correspond au regroupement de tous les segments de ligne des sommets dans la direction donnée (de sorte qu'une tour ou un évêque n'a pas à les parcourir un par un). Lae@t@#
ligne 6 place ensuite les arêtes entre chaque paire de sommets dans le même composant connecté, qui sont ensuiteFlatten
éditées dans un seul graphique. Ainsi, les lignes 6 à 8 définissent le graphique de la toury@r
et le graphique de l'évêquey@b
.Enfin, les lignes 9 à 11 choisissent les éléments
{b, k, n, r}
qui donnent le chemin le plus court entre les deux sommets cibles.FindShortestPath
renverra une erreur et retournera non évalué si un sommet cible n'apparaît pas dans le graphique (ce qui se produira si aucun bord n'en émane), nous utilisonsh@__ -> 0
donc0
plutôt le retour dans ces cas. Et l'absence de chemin entre les sommets valides renvoie une liste de longueur0
, doncMin[z~Complement~{0}]
calcule la longueur du plus petit chemin qui existe réellement, en ignorant les mauvais cas ci-dessus.la source
f
dans cette session, mais j'aurais dû la changer avant la soumission!