feat(encode): add n-queens encoding
This commit is contained in:
1 parent
3854d42178
commit
61c0449d7f
1 file changed
+48
@@ -0,0 +1,48 @@
|
|||||||
|
module Sift.Encode.Queens
|
||||||
|
( queens
|
||||||
|
, queensCell
|
||||||
|
, decodeQueens
|
||||||
|
, validQueens
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Sift.Types
|
||||||
|
import Sift.Encode.Cardinality
|
||||||
|
import qualified Data.Map.Strict as Map
|
||||||
|
|
||||||
|
queensCell :: Int -> Int -> Int -> Var
|
||||||
|
queensCell n r c = Var ((r - 1) * n + c)
|
||||||
|
|
||||||
|
queens :: Int -> CNF
|
||||||
|
queens n = CNF (rowExactly ++ colAtMost ++ diagAtMost)
|
||||||
|
where
|
||||||
|
cell r c = posLit (queensCell n r c)
|
||||||
|
rowExactly = concat
|
||||||
|
[ exactlyOne [ cell r c | c <- [1 .. n] ] | r <- [1 .. n] ]
|
||||||
|
colAtMost = concat
|
||||||
|
[ atMostOne [ cell r c | r <- [1 .. n] ] | c <- [1 .. n] ]
|
||||||
|
diagAtMost = concatMap atMostOne (downDiagonals ++ upDiagonals)
|
||||||
|
downDiagonals =
|
||||||
|
[ [ cell r c | r <- [1 .. n], c <- [1 .. n], r - c == k ]
|
||||||
|
| k <- [negate (n - 1) .. n - 1] ]
|
||||||
|
upDiagonals =
|
||||||
|
[ [ cell r c | r <- [1 .. n], c <- [1 .. n], r + c == k ]
|
||||||
|
| k <- [2 .. 2 * n] ]
|
||||||
|
|
||||||
|
decodeQueens :: Int -> Assignment -> [(Int, Int)]
|
||||||
|
decodeQueens n asn =
|
||||||
|
[ (r, c)
|
||||||
|
| r <- [1 .. n], c <- [1 .. n]
|
||||||
|
, Map.findWithDefault False (queensCell n r c) asn ]
|
||||||
|
|
||||||
|
validQueens :: Int -> Assignment -> Bool
|
||||||
|
validQueens n asn =
|
||||||
|
length placed == n
|
||||||
|
&& distinct (map fst placed)
|
||||||
|
&& distinct (map snd placed)
|
||||||
|
&& distinct (map (\(r, c) -> r - c) placed)
|
||||||
|
&& distinct (map (\(r, c) -> r + c) placed)
|
||||||
|
where
|
||||||
|
placed = decodeQueens n asn
|
||||||
|
|
||||||
|
distinct :: Ord a => [a] -> Bool
|
||||||
|
distinct xs = length xs == Map.size (Map.fromList (zip xs (repeat ())))
|
||||||
Reference in new issue
Block a user