RosettaCodeData/Task/N-queens-problem/Haskell/n-queens-problem-4.hs

42 lines
1.3 KiB
Haskell

import Data.List (transpose, intercalate)
import Data.Bool (bool)
queenPuzzle :: Int -> Int -> [[Int]]
queenPuzzle nRows nCols
| nRows <= 0 = [[]]
| otherwise =
foldr (\qs a ->
a ++ foldr (\iCol b -> bool b (b ++ [qs ++ [iCol]])
(safe (nRows - 1) iCol qs))
[]
[1 .. nCols])
[]
(queenPuzzle (nRows - 1) nCols)
safe :: Int -> Int -> [Int] -> Bool
safe iRow iCol qs =
(not . or) $ zipWith (\sc sr -> (iCol == sc) ||
(sc + sr == (iCol + iRow)) ||
(sc - sr == (iCol - iRow)))
qs
[0 .. iRow - 1]
-- TEST ---------------------------------------------------
-- 10 columns of solutions for the 7*7 board:
showSolutions :: Int -> Int -> [String]
showSolutions nCols nSize =
map (unlines . map (intercalate " ") . transpose . map boardLines)
$ chunksOf nCols (queenPuzzle nSize nSize)
where
boardLines rows =
[map (bool '.' '♛' . (== r)) [1 .. (length rows)] | r <- rows]
chunksOf :: Int -> [a] -> [[a]]
chunksOf i xs = splits xs
where
splits [] = []
splits l = (take i l) : splits (drop i l)
main :: IO ()
main = (putStrLn . unlines) $ showSolutions 10 7