[nhc-users] -b vs. -p
Saswat Anand
saswat@comp.nus.edu.sg
Fri, 12 Apr 2002 16:21:31 +0800 (GMT-8)
Sorry. Here is my Program.
module Main(main) where
import IOExtras
type Var = Int
type Val = Int
data Assignment = Var := Val deriving (Eq,Show)
data Assgn = Tree Assignment [Assgn] deriving (Eq,Show)
main = do putStrLn $ "Solutions = " ++ (show $ length $ results (bb [1..9]
9) 9)
c <- readIORef counter
putStrLn $ "Checks = " ++ show c
cc :: [[Assignment]->Bool] -> Assgn -> [Assgn]
cc cons t = fun [] 0 t
where fun part var (Tree t cs) =
let new_ass = part++[t]
new_chi = concatMap (fun new_ass (var+1)) cs
in if (cons!!var) new_ass
then [Tree t new_chi]
else []
bb :: [Var] -> Int -> [Assgn]
bb vars n = let cons = take n $ (true : [ f a | a <- [2..]])
f a = foldl1 (&) [check a m | m <- [1..a-1]]
in concatMap (cc cons) (fun vars)
where fun (v:vs) = [Tree (v:=x) (fun vs) | x <- [1..n]]
fun [] = []
check :: Int -> Int -> [Assignment] -> Bool
check m n ass = safe (ass!!(m-1)) (ass!!(n-1))
true :: [Assignment] -> Bool
true _ = True
(&) :: ([Assignment]->Bool) -> ([Assignment]->Bool) ->
([Assignment]->Bool)
f1 & f2 = \ints -> f1 ints && f2 ints
safe :: Assignment -> Assignment -> Bool
safe (i:=j) (m:=n) = unsafePerformIO $
do c <- readIORef counter
writeIORef counter $! (c+1)
return $ not (j==n || i+j==m+n || i-j==m-n)
results :: [Assgn] -> Int -> [[Assignment]]
results t no= concatMap ((filter (\l->length l == no)).flatten) t
where flatten (Tree t []) = [[t]]
flatten (Tree t cs) = map (t:) (concatMap flatten cs)
counter :: IORef Integer
counter = unsafePerformIO $ newIORef (0::Integer)