In [1]:
import Data.List
In [2]:
data ExprTree = One | Zero
| And ExprTree ExprTree
| Or ExprTree ExprTree
| Xor ExprTree ExprTree
deriving (Show)
In [3]:
makeTrees :: String -> [ExprTree]
makeTrees "0" = [Zero]
makeTrees "1" = [One]
makeTrees xs =
let
makeNodes (op, ls, rs) =
[action l r | l <- (makeTrees ls), r <- (makeTrees rs)]
where action = case op of '|' -> Or
'&' -> And
'^' -> Xor
in
concatMap makeNodes splits
where
splits =
map (\(ls, op:rs) -> (op, ls, rs)) $
map (`splitAt` xs) $ takeWhile (< length xs) [1,3..]
In [4]:
import Data.Bits
In [5]:
evalTree :: ExprTree -> Bool
evalTree Zero = False
evalTree One = True
evalTree (And left right) = (evalTree left) && (evalTree right)
evalTree (Or left right) = (evalTree left) || (evalTree right)
evalTree (Xor left right) = (evalTree left) `xor` (evalTree right)
In [6]:
ways :: String -> Bool -> Int
ways expr result =
length $ filter (== result) $ map evalTree $ makeTrees expr
In [7]:
ways "1^0|0|1" False
ways "0&0&0&1^1|0" True