module Main where
import Data.List(intersperse)
type Queen = (Int,Int)
type Board = [Queen]
dispBoard = (sep++) . (++sep) . unlines . map dispQ
where dispQ (_,k) = ('|':) . (++"|") . intersperse ' '
$ r k ++ 'Q' : r (7-k)
where r = flip take $ repeat '·'
sep = "+---------------+\n"
attacks (ax,ay) (bx,by) = ax == bx
|| ay == by
|| abs (ax - bx) == abs (ay - by)
none :: Foldable t => (α -> Bool) -> t α -> Bool
none = (not.) . any
legal q = none . attacks $ q
solve = s []
where s board | line == 8 = [board]
| otherwise = concatMap s possibles
where line = length board
possibles = [((line,y):board) | y <- [0..7], legal (line,y) board]
main = putStrLn $
(++"\n"++show (length solutions)++" solutions.")
. unlines . map dispBoard $ solutions
where solutions = solve