{-# OPTIONS_GHC -Wall -Werror #-}
module Documentation.SBV.Examples.Puzzles.Counts where
import Data.SBV
import Data.List (sortOn)
type Count = SWord8
count :: Count -> [Count] -> [Count]
count :: Count -> [Count] -> [Count]
count Count
n [Count]
cnts = forall a. Mergeable a => SBool -> a -> a -> a
ite (Count
n forall a. OrdSymbolic a => a -> a -> SBool
.< Count
10)
(forall {c} {a}.
(Mergeable c, Num c, Num a, Enum a, EqSymbolic a) =>
a -> [c] -> [c]
upd Count
n [Count]
cnts)
(forall a. Mergeable a => SBool -> a -> a -> a
ite (Count
n forall a. OrdSymbolic a => a -> a -> SBool
.< Count
100)
(forall {c} {a}.
(Mergeable c, Num c, Num a, Enum a, EqSymbolic a) =>
a -> [c] -> [c]
upd Count
d1 (forall {c} {a}.
(Mergeable c, Num c, Num a, Enum a, EqSymbolic a) =>
a -> [c] -> [c]
upd Count
d2 [Count]
cnts))
(forall {c} {a}.
(Mergeable c, Num c, Num a, Enum a, EqSymbolic a) =>
a -> [c] -> [c]
upd Count
d1 (forall {c} {a}.
(Mergeable c, Num c, Num a, Enum a, EqSymbolic a) =>
a -> [c] -> [c]
upd Count
d2 (forall {c} {a}.
(Mergeable c, Num c, Num a, Enum a, EqSymbolic a) =>
a -> [c] -> [c]
upd Count
d3 [Count]
cnts))))
where (Count
r1, Count
d1) = Count
n forall a. SDivisible a => a -> a -> (a, a)
`sQuotRem` Count
10
(Count
d3, Count
d2) = Count
r1 forall a. SDivisible a => a -> a -> (a, a)
`sQuotRem` Count
10
upd :: a -> [c] -> [c]
upd a
d = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall {a}. (Mergeable a, Num a) => a -> a -> a
inc [a
0..]
where inc :: a -> a -> a
inc a
i a
c = forall a. Mergeable a => SBool -> a -> a -> a
ite (a
i forall a. EqSymbolic a => a -> a -> SBool
.== a
d) (a
cforall a. Num a => a -> a -> a
+a
1) a
c
puzzle :: [Count] -> SBool
puzzle :: [Count] -> SBool
puzzle [Count]
cnt = [Count]
cnt forall a. EqSymbolic a => a -> a -> SBool
.== forall a. [a] -> a
last [[Count]]
css
where ones :: [Count]
ones = forall a. Int -> a -> [a]
replicate Int
10 Count
1
css :: [[Count]]
css = [Count]
ones forall a. a -> [a] -> [a]
: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Count -> [Count] -> [Count]
count [Count]
cnt [[Count]]
css
counts :: IO ()
counts :: IO ()
counts = do AllSatResult
res <- forall a. Provable a => a -> IO AllSatResult
allSat forall a b. (a -> b) -> a -> b
$ [Count] -> SBool
puzzle forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` forall a. SymVal a => Int -> Symbolic [SBV a]
mkExistVars Int
10
Int
cnt <- forall a.
SatModel a =>
([(Bool, a)] -> [(Bool, a)])
-> (Int -> (Bool, a) -> IO ()) -> AllSatResult -> IO Int
displayModels (forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn forall a. Show a => a -> String
show) forall {a} {a}. Show a => a -> (a, [Word8]) -> IO ()
disp AllSatResult
res
String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ String
"Found: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
cnt forall a. [a] -> [a] -> [a]
++ String
" solution(s)."
where disp :: a -> (a, [Word8]) -> IO ()
disp a
n (a
_, [Word8]
s) = do String -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ String
"Solution #" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
n
[Word8] -> IO ()
dispSolution [Word8]
s
dispSolution :: [Word8] -> IO ()
dispSolution :: [Word8] -> IO ()
dispSolution [Word8]
ns = String -> IO ()
putStrLn String
soln
where soln :: String
soln = String
"In this sentence, the number of occurrences"
forall a. [a] -> [a] -> [a]
++ String
" of 0 is " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ([Word8]
ns forall a. [a] -> Int -> a
!! Int
0)
forall a. [a] -> [a] -> [a]
++ String
", of 1 is " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ([Word8]
ns forall a. [a] -> Int -> a
!! Int
1)
forall a. [a] -> [a] -> [a]
++ String
", of 2 is " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ([Word8]
ns forall a. [a] -> Int -> a
!! Int
2)
forall a. [a] -> [a] -> [a]
++ String
", of 3 is " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ([Word8]
ns forall a. [a] -> Int -> a
!! Int
3)
forall a. [a] -> [a] -> [a]
++ String
", of 4 is " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ([Word8]
ns forall a. [a] -> Int -> a
!! Int
4)
forall a. [a] -> [a] -> [a]
++ String
", of 5 is " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ([Word8]
ns forall a. [a] -> Int -> a
!! Int
5)
forall a. [a] -> [a] -> [a]
++ String
", of 6 is " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ([Word8]
ns forall a. [a] -> Int -> a
!! Int
6)
forall a. [a] -> [a] -> [a]
++ String
", of 7 is " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ([Word8]
ns forall a. [a] -> Int -> a
!! Int
7)
forall a. [a] -> [a] -> [a]
++ String
", of 8 is " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ([Word8]
ns forall a. [a] -> Int -> a
!! Int
8)
forall a. [a] -> [a] -> [a]
++ String
", of 9 is " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ([Word8]
ns forall a. [a] -> Int -> a
!! Int
9)
forall a. [a] -> [a] -> [a]
++ String
"."
{-# ANN counts ("HLint: ignore Use head" :: String) #-}