-- |-- Module : AOC.Challenge.Day01-- License : BSD3---- Stability : experimental-- Portability : non-portable---- Day 1. See "AOC.Solver" for the types used in this module!moduleAOC.Challenge.Day01(day01a,day01b,knapsack)whereimportAOC.Common(firstJust)importAOC.Solver((:~>)(..))importData.IntSet(IntSet)importData.Type.Nat(Nat(..),Nat1,Nat2,SNat(..),SNatI(..),snat)importText.Read(readMaybe)importqualifiedData.IntSetasISimportqualifiedData.Vec.LazyasVec-- | Given a goal sum and a set of numbers to pick from, finds the @n@-- numbers in the set that add to the goal sum. The number of items-- desired is inferred from the desired length of the return type.knapsack::foralln.SNatIn=>Int-- ^ goal sum->IntSet-- ^ set of options->Maybe(Vec.Vec('Sn)Int)-- ^ resulting n items that sum to the goalknapsack :: forall (n :: Nat).
SNatI n =>
Int -> IntSet -> Maybe (Vec ('S n) Int)
knapsack=caseSNat n
forall (n :: Nat). SNatI n => SNat n
snat::SNatnofSNat n
SZ->\Int
goalIntSet
xs->ifInt
goalInt -> IntSet -> Bool
`IS.member`IntSet
xsthenVec ('S 'Z) Int -> Maybe (Vec ('S 'Z) Int)
forall a. a -> Maybe a
Just(Vec ('S 'Z) Int -> Maybe (Vec ('S 'Z) Int))
-> Vec ('S 'Z) Int -> Maybe (Vec ('S 'Z) Int)
forall a b. (a -> b) -> a -> b
$Int -> Vec ('S 'Z) Int
forall a. a -> Vec ('S 'Z) a
Vec.singletonInt
goalelseMaybe (Vec ('S n) Int)
forall a. Maybe a
NothingSNat n
SS->\Int
goalIntSet
xs->((Int -> Maybe (Vec ('S ('S n1)) Int))
-> [Int] -> Maybe (Vec ('S ('S n1)) Int))
-> [Int]
-> (Int -> Maybe (Vec ('S ('S n1)) Int))
-> Maybe (Vec ('S ('S n1)) Int)
forall a b c. (a -> b -> c) -> b -> a -> c
flip(Int -> Maybe (Vec ('S ('S n1)) Int))
-> [Int] -> Maybe (Vec ('S ('S n1)) Int)
forall (t :: * -> *) a b.
Foldable t =>
(a -> Maybe b) -> t a -> Maybe b
firstJust(IntSet -> [Int]
IS.toListIntSet
xs)((Int -> Maybe (Vec ('S ('S n1)) Int))
-> Maybe (Vec ('S ('S n1)) Int))
-> (Int -> Maybe (Vec ('S ('S n1)) Int))
-> Maybe (Vec ('S ('S n1)) Int)
forall a b. (a -> b) -> a -> b
$\Int
x->letgoal' :: Int
goal'=Int
goalInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
x(IntSet
_,IntSet
ys)=Int -> IntSet -> (IntSet, IntSet)
IS.splitInt
xIntSet
xsin(Int
xInt -> Vec ('S n1) Int -> Vec ('S ('S n1)) Int
forall a (n1 :: Nat). a -> Vec n1 a -> Vec ('S n1) a
Vec.:::)(Vec ('S n1) Int -> Vec ('S ('S n1)) Int)
-> Maybe (Vec ('S n1) Int) -> Maybe (Vec ('S ('S n1)) Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>Int -> IntSet -> Maybe (Vec ('S n1) Int)
forall (n :: Nat).
SNatI n =>
Int -> IntSet -> Maybe (Vec ('S n) Int)
knapsackInt
goal'IntSet
ysday01a::[Int]:~>Intday01a :: [Int] :~> Int
day01a=MkSol :: forall a b.
(String -> Maybe a)
-> ((?dyno::DynoMap) => a -> Maybe b) -> (b -> String) -> a :~> b
MkSol{sParse :: String -> Maybe [Int]
sParse=(String -> Maybe Int) -> [String] -> Maybe [Int]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverseString -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe([String] -> Maybe [Int])
-> (String -> [String]) -> String -> Maybe [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.String -> [String]
lines,sShow :: Int -> String
sShow=Int -> String
forall a. Show a => a -> String
show,sSolve :: (?dyno::DynoMap) => [Int] -> Maybe Int
sSolve=(Vec ('S ('S 'Z)) Int -> Int)
-> Maybe (Vec ('S ('S 'Z)) Int) -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmapVec ('S ('S 'Z)) Int -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product(Maybe (Vec ('S ('S 'Z)) Int) -> Maybe Int)
-> ([Int] -> Maybe (Vec ('S ('S 'Z)) Int)) -> [Int] -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
.forall (n :: Nat).
SNatI n =>
Int -> IntSet -> Maybe (Vec ('S n) Int)
knapsack@Nat1Int
2020(IntSet -> Maybe (Vec ('S ('S 'Z)) Int))
-> ([Int] -> IntSet) -> [Int] -> Maybe (Vec ('S ('S 'Z)) Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.[Int] -> IntSet
IS.fromList}day01b::[Int]:~>Intday01b :: [Int] :~> Int
day01b=MkSol :: forall a b.
(String -> Maybe a)
-> ((?dyno::DynoMap) => a -> Maybe b) -> (b -> String) -> a :~> b
MkSol{sParse :: String -> Maybe [Int]
sParse=(String -> Maybe Int) -> [String] -> Maybe [Int]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverseString -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe([String] -> Maybe [Int])
-> (String -> [String]) -> String -> Maybe [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.String -> [String]
lines,sShow :: Int -> String
sShow=Int -> String
forall a. Show a => a -> String
show,sSolve :: (?dyno::DynoMap) => [Int] -> Maybe Int
sSolve=(Vec ('S ('S ('S 'Z))) Int -> Int)
-> Maybe (Vec ('S ('S ('S 'Z))) Int) -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmapVec ('S ('S ('S 'Z))) Int -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product(Maybe (Vec ('S ('S ('S 'Z))) Int) -> Maybe Int)
-> ([Int] -> Maybe (Vec ('S ('S ('S 'Z))) Int))
-> [Int]
-> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
.forall (n :: Nat).
SNatI n =>
Int -> IntSet -> Maybe (Vec ('S n) Int)
knapsack@Nat2Int
2020(IntSet -> Maybe (Vec ('S ('S ('S 'Z))) Int))
-> ([Int] -> IntSet) -> [Int] -> Maybe (Vec ('S ('S ('S 'Z))) Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.[Int] -> IntSet
IS.fromList}