module MonusWeightedSearch.Examples.SubsetSum where
import Control.Monad.Heap
import Data.Monus.Dist
import Control.Monad.Writer
import Data.Maybe
import Control.Monad (filterM, guard)
inclusion :: Monad m => HeapT Dist m Bool
inclusion :: forall (m :: Type -> Type). Monad m => HeapT Dist m Bool
inclusion = [(Bool, Dist)] -> HeapT Dist m Bool
forall (m :: Type -> Type) a w.
Applicative m =>
[(a, w)] -> HeapT w m a
fromList [(Bool
False,Dist
0),(Bool
True,Dist
1)]
shortest :: Int -> [Int] -> [Int]
shortest :: Int -> [Int] -> [Int]
shortest Int
t [Int]
xs = (Dist, [Int]) -> [Int]
forall a b. (a, b) -> b
snd ((Dist, [Int]) -> [Int])
-> (Heap Dist [Int] -> (Dist, [Int])) -> Heap Dist [Int] -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe (Dist, [Int]) -> (Dist, [Int])
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (Dist, [Int]) -> (Dist, [Int]))
-> (Heap Dist [Int] -> Maybe (Dist, [Int]))
-> Heap Dist [Int]
-> (Dist, [Int])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Heap Dist [Int] -> Maybe (Dist, [Int])
forall w a. Monus w => Heap w a -> Maybe (w, a)
best (Heap Dist [Int] -> [Int]) -> Heap Dist [Int] -> [Int]
forall a b. (a -> b) -> a -> b
$ do
[Int]
subset <- (Int -> HeapT Dist Identity Bool) -> [Int] -> Heap Dist [Int]
forall (m :: Type -> Type) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM (HeapT Dist Identity Bool -> Int -> HeapT Dist Identity Bool
forall a b. a -> b -> a
const HeapT Dist Identity Bool
forall (m :: Type -> Type). Monad m => HeapT Dist m Bool
inclusion) [Int]
xs
Bool -> HeapT Dist Identity ()
forall (f :: Type -> Type). Alternative f => Bool -> f ()
guard ([Int] -> Int
forall (t :: Type -> Type) a. (Foldable t, Num a) => t a -> a
sum [Int]
subset Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
t)
pure [Int]
subset