-- |-- Module : AOC.Challenge.Day09-- License : BSD3---- Stability : experimental-- Portability : non-portable---- Day 9. See "AOC.Solver" for the types used in this module!moduleAOC.Challenge.Day09(day09a,day09b)whereimportAOC.Common(slidingWindows,firstJust)importAOC.Solver((:~>)(..),dyno_)importControl.Monad(guard)importData.Foldable(toList)importData.List(scanl',tails)importData.Sequence(Seq(..))importText.Read(readMaybe)importqualifiedData.VectorasVisBad::SeqInt->MaybeIntisBad :: Seq Int -> Maybe Int
isBadSeq Int
xs0=do(Seq Int
xs:|>Int
x)<-Seq Int -> Maybe (Seq Int)
forall (f :: * -> *) a. Applicative f => a -> f a
pureSeq Int
xs0letbadCheck :: Bool
badCheck=[()] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
nulldoInt
y:[Int]
ys<-[Int] -> [[Int]]
forall a. [a] -> [[a]]
tails(Seq Int -> [Int]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toListSeq Int
xs)Int
z<-[Int]
ysBool -> [()]
forall (f :: * -> *). Alternative f => Bool -> f ()
guard(Bool -> [()]) -> Bool -> [()]
forall a b. (a -> b) -> a -> b
$(Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
z)Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
xInt
xInt -> Maybe () -> Maybe Int
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guardBool
badCheckoddOneOut::Int->[Int]->MaybeIntoddOneOut :: Int -> [Int] -> Maybe Int
oddOneOutInt
w=(Seq Int -> Maybe Int) -> [Seq Int] -> Maybe Int
forall (t :: * -> *) a b.
Foldable t =>
(a -> Maybe b) -> t a -> Maybe b
firstJustSeq Int -> Maybe Int
isBad([Seq Int] -> Maybe Int)
-> ([Int] -> [Seq Int]) -> [Int] -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Int -> [Int] -> [Seq Int]
forall a. Int -> [a] -> [Seq a]
slidingWindows(Int
wInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)day09a::[Int]:~>Intday09a :: [Int] :~> Int
day09a=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=Int -> [Int] -> Maybe Int
oddOneOut(String -> Int -> Int
forall a. (Typeable a, ?dyno::DynoMap) => String -> a -> a
dyno_String
"window"Int
25)}findBounds::V.VectorInt->Int->Maybe(Int,Int)findBounds :: Vector Int -> Int -> Maybe (Int, Int)
findBoundsVector Int
nsInt
goal=Int -> Int -> Maybe (Int, Int)
goInt
0Int
1wherego :: Int -> Int -> Maybe (Int, Int)
go!Int
i!Int
j=doInt
x<-Vector Int
nsVector Int -> Int -> Maybe Int
forall a. Vector a -> Int -> Maybe a
V.!?Int
iInt
y<-Vector Int
nsVector Int -> Int -> Maybe Int
forall a. Vector a -> Int -> Maybe a
V.!?Int
jcaseInt -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare(Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
x)Int
goalofOrdering
LT->Int -> Int -> Maybe (Int, Int)
goInt
i(Int
jInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)Ordering
EQ->(Int, Int) -> Maybe (Int, Int)
forall (f :: * -> *) a. Applicative f => a -> f a
pure(Int
i,Int
j)Ordering
GT->Int -> Int -> Maybe (Int, Int)
go(Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)Int
jday09b::[Int]:~>(Int,Int)day09b :: [Int] :~> (Int, Int)
day09b=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, Int) -> String
sShow=\(Int
x,Int
y)->Int -> String
forall a. Show a => a -> String
show(Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
y),sSolve :: (?dyno::DynoMap) => [Int] -> Maybe (Int, Int)
sSolve=\[Int]
ns->doInt
goal<-Int -> [Int] -> Maybe Int
oddOneOut(String -> Int -> Int
forall a. (Typeable a, ?dyno::DynoMap) => String -> a -> a
dyno_String
"window"Int
25)[Int]
nsletcumsum :: Vector Int
cumsum=[Int] -> Vector Int
forall a. [a] -> Vector a
V.fromList((Int -> Int -> Int) -> Int -> [Int] -> [Int]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanl'Int -> Int -> Int
forall a. Num a => a -> a -> a
(+)Int
0[Int]
ns)(Int
i,Int
j)<-Vector Int -> Int -> Maybe (Int, Int)
findBoundsVector Int
cumsumInt
goalletxs :: [Int]
xs=Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take(Int
jInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i)([Int] -> [Int]) -> ([Int] -> [Int]) -> [Int] -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
dropInt
i([Int] -> [Int]) -> [Int] -> [Int]
forall a b. (a -> b) -> a -> b
$[Int]
ns(Int, Int) -> Maybe (Int, Int)
forall (f :: * -> *) a. Applicative f => a -> f a
pure([Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum[Int]
xs,[Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum[Int]
xs)}-- an implementation using a priority search queue, which should have-- efficient lookup and popping. but unfortunately it has too much overhead-- to offer any overall advantage-- isBad2 :: IntPSQ Int () -> Maybe Int-- isBad2 q = do-- (goal, _, _, xs) <- IntPSQ.minView q-- let badCheck = null do-- (x,_,_) <- IntPSQ.toList xs-- let y = goal - x-- guard $ y > x-- guard $ y `IntPSQ.member` xs-- goal <$ guard badCheck-- oddOneOut2 :: Int -> [Int] -> Maybe Int-- oddOneOut2 w = firstJust isBad2-- . reverse-- . sortedSlidingWindowsInt (w + 1)-- . reverse-- . map (,())