42 lines
1.3 KiB
Haskell
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
|