2 import qualified Data.Set as S
5 data Queen = Queen Int Int -- row, column
6 deriving (Show, Eq, Ord)
11 let grid = mkGrid text
13 let solutions = solve grid
14 print $ length solutions
16 solve :: S.Set Queen -> [S.Set Queen]
18 do cols <- permutations [0..7]
19 let queens = S.fromList [uncurry Queen p | p <- zip [0..7] cols]
20 guard $ S.null $ S.intersection queens forbiddens
21 let posDiagonals = S.map posDiagonalOf queens
22 let negDiagonals = S.map negDiagonalOf queens
23 guard $ S.size posDiagonals == 8
24 guard $ S.size negDiagonals == 8
27 posDiagonalOf, negDiagonalOf :: Queen -> Int
28 posDiagonalOf (Queen r c) = c - r
29 negDiagonalOf (Queen r c) = c + r
31 mkGrid :: String -> S.Set Queen
32 mkGrid text = S.fromList forbiddens
33 where rows = lines text
35 c = (length $ head rows) - 1
36 forbiddens = [Queen i j | i <- [0..r], j <- [0..c], rows !! i !! j == '*' ]