Advertisement
Yurry

Figures placement task

Jan 28th, 2014
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Data.Set hiding (foldr, map)
  2.  
  3. data Fig = Q | R | B | K | N
  4.     deriving (Eq, Ord)
  5.  
  6. type Cell = (Int, Int)
  7. type Placed = (Cell, Fig)
  8.  
  9. fac n = foldr (*) 1 [1 .. n]
  10.  
  11. layoutsCount :: Int -> Int -> [(Int, Fig)] -> Int
  12. layoutsCount m n f = length (layouts [] allCells ungroup) `quot` repeats where
  13.     ungroup = concatMap (uncurry replicate) f
  14.     repeats = product $ map (fac . fst) f
  15.     allCells = fromList [(x, y) | x <- [1 .. m], y <- [1 .. n]]
  16.     layouts :: [Placed] -> Set Cell -> [Fig] -> [[Placed]]
  17.     layouts cur _ [] = [cur]
  18.     layouts cur cells (f:fs) = concat
  19.         [ layouts ((c, f):cur) (cells \\ nc) fs
  20.         | c <- toList cells
  21.         , let nc = fromList $ attacked c f
  22.         , all (flip notMember nc . fst) cur
  23.         ]
  24.  
  25.     attacked c      Q = attacked c R ++ attacked c B
  26.     attacked (x, y) R = [(i, y) | i <- [1 .. m]] ++ [(x, j) | j <- [1 .. n]]
  27.     attacked (x, y) B = [(i, i - o) | let o = x - y, i <- [max 1 (1 + o) .. min m (n + o)]]
  28.                      ++ [(i, o - i) | let o = x + y, i <- [max 1 (o - n) .. min m (o - 1)]]
  29.     attacked (x, y) K = [(x + i, y + j) | i <- [-1 .. 1], j <- [-1 .. 1]]
  30.     attacked (x, y) N = (x, y):[(x + i, y + j) | i <- [-1, 1], j <- [-2, 2]]
  31.                      ++ [(x + i, y + j) | i <- [-2, 2], j <- [-1, 1]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement