Knight's tour: Difference between revisions

Content added Content deleted
No edit summary
(→‎{{header|Haskell}}: Applied hlint and hindent – slightly simplified the type of the input, and slightly uncluttered the main :: IO() function)
Line 3,031: Line 3,031:


=={{header|Haskell}}==
=={{header|Haskell}}==
<lang Haskell>
<lang Haskell>import Data.Char (ord, chr)
import System (getArgs)
import Data.Char (ord, chr)
import Data.List (minimumBy, (\\), intercalate, sort)
import Data.Ord (comparing)
import Data.Ord (comparing)
import Data.List (minimumBy, (\\), intercalate, sort)


type Square = (Int, Int)
type Square = (Int, Int)


board :: [Square]
board :: [Square]
board =
board = [ (x,y) | x <- [1..8], y <- [1..8] ]
[ (x, y)
| x <- [1 .. 8]
, y <- [1 .. 8] ]


knightMoves :: Square -> [Square]
knightMoves :: Square -> [Square]
knightMoves (x,y) = filter (flip elem board) jumps
knightMoves (x, y) = filter (`elem` board) jumps
where
where jumps = [ (x+i,y+j) | i <- jv, j <- jv, abs i /= abs j ]
jv = [1,-1,2,-2]
jumps =
[ (x + i, y + j)
| i <- jv
, j <- jv
, abs i /= abs j ]
jv = [1, -1, 2, -2]


knightTour :: [Square] -> [Square]
knightTour :: [Square] -> [Square]
knightTour moves
knightTour moves
| candMoves == [] = reverse moves
| null candMoves = reverse moves
| otherwise = knightTour $ newSquare : moves
| otherwise = knightTour $ newSquare : moves
where
where newSquare = minimumBy (comparing (length . findMoves)) candMoves
candMoves = findMoves $ head moves
newSquare = minimumBy (comparing (length . findMoves)) candMoves
findMoves sq = knightMoves sq \\ moves
candMoves = findMoves $ head moves
findMoves = (\\ moves) . knightMoves


main :: IO ()
toSq :: String -> (Int, Int)
toSq [x, y] = (ord x - 96, ord y - 48)
main = do
sq <- fmap (toSq . head) getArgs
printTour $ map toAlg $ knightTour [sq]
where toAlg (x,y) = [chr (x + 96), chr (y + 48)]
toSq [x,y] = ((ord x) - 96, (ord y) - 48)
printTour [] = return ()
printTour tour = do
putStrLn $ intercalate " -> " $ take 8 tour
printTour $ drop 8 tour
</lang>


toAlg :: (Int, Int) -> String
Output:
toAlg (x, y) = [chr (x + 96), chr (y + 48)]
<pre>

e5 -> f7 -> h8 -> g6 -> h4 -> g2 -> e1 -> f3
-- TEST -----------------------------------------------------------------------
sq :: (Int, Int)
sq = toSq "e5" -- Input: starting position on the bord, e.g. (5, 5) as "e5"

main :: IO ()
main = printTour $ toAlg <$> knightTour [sq]
where
printTour [] = return ()
printTour tour = do
putStrLn $ intercalate " -> " $ take 8 tour
printTour $ drop 8 tour</lang>
{{Out}}
<pre>e5 -> f7 -> h8 -> g6 -> h4 -> g2 -> e1 -> f3
g1 -> h3 -> g5 -> h7 -> f8 -> d7 -> b8 -> a6
g1 -> h3 -> g5 -> h7 -> f8 -> d7 -> b8 -> a6
b4 -> a2 -> c1 -> d3 -> b2 -> a4 -> b6 -> a8
b4 -> a2 -> c1 -> d3 -> b2 -> a4 -> b6 -> a8
Line 3,076: Line 3,087:
a5 -> c6 -> a7 -> c8 -> d6 -> b5 -> d4 -> e2
a5 -> c6 -> a7 -> c8 -> d6 -> b5 -> d4 -> e2
c3 -> d1 -> f2 -> h1 -> g3 -> e4 -> f6 -> g8
c3 -> d1 -> f2 -> h1 -> g3 -> e4 -> f6 -> g8
h6 -> g4 -> h2 -> f1 -> e3 -> f5 -> e7 -> d5
h6 -> g4 -> h2 -> f1 -> e3 -> f5 -> e7 -> d5</pre>
</pre>


=={{header|Icon}} and {{header|Unicon}}==
=={{header|Icon}} and {{header|Unicon}}==