From 4087698696ed09477c3b5073f3d4d93d85c0a632 Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Tue, 18 Jul 2023 15:22:56 +0100 Subject: [PATCH] Reworking day 16 --- advent-of-code22.cabal | 57 +++++ advent16/Main.hs | 252 ++++++++++++++------- advent16/MainBeam.hs | 362 +++++++++++++++++++++++++++++ advent16/MainCustomClosed.hs | 401 +++++++++++++++++++++++++++++++++ advent16/MainEstSort.hs | 352 +++++++++++++++++++++++++++++ advent16/MainOriginal.hs | 275 ++++++++++++++++++++++ advent16/MainOriginalNoBeam.hs | 275 ++++++++++++++++++++++ advent16/MainSPar.hs | 323 ++++++++++++++++++++++++++ advent16/MainSubsets.hs | 309 +++++++++++++++++++++++++ advent16/a16-solution.dot.png | Bin 0 -> 202269 bytes advent16/a16.dot | 94 ++++++++ 11 files changed, 2618 insertions(+), 82 deletions(-) create mode 100644 advent16/MainBeam.hs create mode 100644 advent16/MainCustomClosed.hs create mode 100644 advent16/MainEstSort.hs create mode 100644 advent16/MainOriginal.hs create mode 100644 advent16/MainOriginalNoBeam.hs create mode 100644 advent16/MainSPar.hs create mode 100644 advent16/MainSubsets.hs create mode 100644 advent16/a16-solution.dot.png create mode 100644 advent16/a16.dot diff --git a/advent-of-code22.cabal b/advent-of-code22.cabal index 5a5315d..8a1b109 100644 --- a/advent-of-code22.cabal +++ b/advent-of-code22.cabal @@ -206,6 +206,63 @@ executable advent15prof -eventlog -rtsopts "-with-rtsopts=-N -p -s -hT -ls" +executable advent16original + import: common-extensions, build-directives + main-is: advent16/MainOriginal.hs + build-depends: text, attoparsec, containers, pqueue, mtl, lens, split + +executable advent16originalnobeam + import: common-extensions, build-directives + main-is: advent16/MainOriginalNoBeam.hs + build-depends: text, attoparsec, containers, pqueue, mtl, lens, split + +executable advent16sort + import: common-extensions, build-directives + main-is: advent16/MainEstSort.hs + build-depends: text, attoparsec, containers, pqueue, mtl, lens, split + +executable advent16beam + import: common-extensions, build-directives + main-is: advent16/MainBeam.hs + build-depends: text, attoparsec, containers, pqueue, mtl, lens, split + +executable advent16customclosed + import: common-extensions, build-directives + main-is: advent16/MainCustomClosed.hs + build-depends: text, attoparsec, containers, pqueue, mtl, lens, split + +executable advent16spar + import: common-extensions, build-directives + main-is: advent16/MainSPar.hs + build-depends: text, attoparsec, containers, pqueue, mtl, lens, split, parallel, deepseq + +executable advent16sparprof + import: common-extensions, build-directives + main-is: advent16/MainSPar.hs + build-depends: text, attoparsec, containers, pqueue, mtl, lens, split, parallel, deepseq + ghc-options: -O2 + -Wall + -threaded + -eventlog + -fprof-auto + -rtsopts "-with-rtsopts=-N -p -s -hT -ls" + +executable advent16subsets + import: common-extensions, build-directives + main-is: advent16/MainSubsets.hs + build-depends: text, attoparsec, containers, pqueue, mtl, lens, split + +executable advent16subsetsprof + import: common-extensions, build-directives + main-is: advent16/MainSubsets.hs + build-depends: text, attoparsec, containers, pqueue, mtl, lens, split + ghc-options: -O2 + -Wall + -threaded + -eventlog + -fprof-auto + -rtsopts "-with-rtsopts=-N -p -s -hT -ls" + executable advent16 import: common-extensions, build-directives main-is: advent16/Main.hs diff --git a/advent16/Main.hs b/advent16/Main.hs index 7db601d..30d0843 100644 --- a/advent16/Main.hs +++ b/advent16/Main.hs @@ -1,6 +1,6 @@ -- Writeup at https://work.njae.me.uk/2022/12/17/advent-of-code-2022-day-16/ --- import Debug.Trace +import Debug.Trace import AoC import Data.Text (Text) @@ -12,39 +12,44 @@ import qualified Data.Set as S import qualified Data.Sequence as Q import qualified Data.Map.Strict as M import Data.Map.Strict ((!)) -import Data.Sequence ((|>)) +-- import Data.Sequence ((|>), Seq((:|>)), ViewR ((:>))) +import Data.Sequence ( (|>), Seq((:|>)) ) import Data.List import Data.List.Split (chunksOf) import Data.Ord import Control.Monad.Reader import Control.Lens hiding ((<|), (|>), (:>), (:<), indices) --- pattern Empty <- (Q.viewl -> Q.EmptyL) where Empty = Q.empty --- pattern x :< xs <- (Q.viewl -> x Q.:< xs) where (:<) = (Q.<|) --- pattern xs :> x <- (Q.viewr -> xs Q.:> x) where (:>) = (Q.|>) type RoomID = String +data Tunnel = Tunnel { _tunnelTo :: RoomID, _tunnelLength :: Int} + deriving (Eq, Show, Ord) +makeLenses ''Tunnel + data Room = Room { _flowRate :: Int - , _tunnels :: [RoomID] + , _tunnels :: S.Set Tunnel } deriving (Eq, Show, Ord) makeLenses ''Room type Cave = M.Map RoomID Room -data TimedCave = TimedCave { getCave :: Cave, getTimeLimit :: Int} +data TimedCave = TimedCave { getCave :: Cave, getTimeLimit :: Int , getSortedRooms :: [RoomID]} type CaveContext = Reader TimedCave data SingleSearchState = SingleSearchState { _currentRoom :: RoomID + , _currentTime :: Int , _sOpenValves :: S.Set RoomID } deriving (Eq, Show, Ord) makeLenses ''SingleSearchState data DoubleSearchState = DoubleSearchState { _personRoom :: RoomID + , _personTime :: Int , _elephantRoom :: RoomID + , _elephantTime :: Int , _dOpenValves :: S.Set RoomID } deriving (Eq, Show, Ord) makeLenses ''DoubleSearchState @@ -59,17 +64,24 @@ makeLenses ''Agendum type Agenda s = P.MaxPQueue Int (Agendum s) -type ExploredStates s = S.Set (s, Int, Int) +-- state, total flowed so far +type ExploredStates s = S.Set (s, Int) class (Eq s, Ord s, Show s) => SearchState s where emptySearchState :: RoomID -> s currentFlow :: s -> CaveContext Int + timeOf :: s -> Int successors :: s -> CaveContext (Q.Seq s) - estimateBenefit :: s -> Int -> CaveContext Int + -- estimateBenefit :: s -> Int -> CaveContext Int + estimateBenefit :: s -> CaveContext Int instance SearchState SingleSearchState where - emptySearchState startID = SingleSearchState { _currentRoom = startID, _sOpenValves = S.empty } + emptySearchState startID = SingleSearchState + { _currentRoom = startID + , _currentTime = 0 + , _sOpenValves = S.empty + } currentFlow state = do cave <- asks getCave @@ -77,29 +89,31 @@ instance SearchState SingleSearchState where let presentRooms = cave `M.restrictKeys` valves return $ sumOf (folded . flowRate) presentRooms + timeOf state = state ^. currentTime + successors state = do isFF <- isFullFlow state + -- cave <- asks getCave + timeLimit <- asks getTimeLimit let here = state ^. currentRoom let opened = state ^. sOpenValves - succPairs <- personSuccessor here opened - let succStates = - [ SingleSearchState - { _currentRoom = r - , _sOpenValves = o - } - | (r, o) <- succPairs - ] - if isFF - then return $ Q.singleton state - else return $ Q.fromList succStates - - estimateBenefit here timeElapsed = + let now = state ^. currentTime + succs <- agentSuccessor now opened now here + let succStates = Q.fromList succs + if isFF || (Q.null succStates) + then return $ Q.singleton (state & currentTime .~ timeLimit) + else return succStates + + estimateBenefit here = do cave <- asks getCave timeLimit <- asks getTimeLimit - let timeRemaining = timeLimit - (timeElapsed + 2) + let timeRemaining = timeLimit - (timeOf here) cf <- currentFlow here - let closedValves = (cave `M.withoutKeys` (here ^. sOpenValves)) ^.. folded . flowRate - let sortedClosedValves = sortOn Down closedValves + -- let closedValves = (cave `M.withoutKeys` (here ^. sOpenValves)) ^.. folded . flowRate + -- let sortedClosedValves = sortOn Down closedValves + sortedValves <- asks getSortedRooms + let opened = here ^. sOpenValves + let sortedClosedValves = [(cave ! v) ^. flowRate | v <- sortedValves, v `S.notMember` opened] let otherValveFlows = sum $ zipWith (*) [timeRemaining, (timeRemaining - 2) .. 0] sortedClosedValves return $ (cf * timeRemaining) + otherValveFlows @@ -107,44 +121,64 @@ instance SearchState SingleSearchState where instance SearchState DoubleSearchState where emptySearchState startID = DoubleSearchState { _personRoom = startID + , _personTime = 0 , _elephantRoom = startID + , _elephantTime = 0 , _dOpenValves = S.empty } currentFlow state = do cave <- asks getCave - let valves = state ^. dOpenValves - let presentRooms = cave `M.restrictKeys` valves - return $ sumOf (folded . flowRate) presentRooms + let valves = S.toList $ state ^. dOpenValves + return $ sum $ fmap (\v -> (cave ! v) ^. flowRate) valves + -- let presentRooms = cave `M.restrictKeys` valves + -- return $ sumOf (folded . flowRate) presentRooms + + timeOf state = min (state ^. personTime) (state ^. elephantTime) successors state = do isFF <- isFullFlow state + -- cave <- asks getCave + timeLimit <- asks getTimeLimit + let opened = state ^. dOpenValves + let pNow = state ^. personTime + let eNow = state ^. elephantTime + let now = min pNow eNow let pHere = state ^. personRoom let eHere = state ^. elephantRoom - let opened = state ^. dOpenValves - pSuccPairs <- personSuccessor pHere opened - eSuccPairs <- personSuccessor eHere opened - let succStates = - [ DoubleSearchState - { _personRoom = p - , _elephantRoom = e - , _dOpenValves = S.union po eo - } - | (p, po) <- pSuccPairs - , (e, eo) <- eSuccPairs - ] - if isFF - then return $ Q.singleton state - else return $ Q.fromList succStates - - estimateBenefit here timeElapsed = + pNexts <- agentSuccessor now opened pNow pHere + eNexts <- agentSuccessor now opened eNow eHere + let nexts = [ state & personRoom .~ (p ^. currentRoom) + & personTime .~ (p ^. currentTime) + & elephantRoom .~ (e ^. currentRoom) + & elephantTime .~ (e ^. currentTime) + & dOpenValves %~ (S.union (p ^. sOpenValves) . S.union (e ^. sOpenValves)) + | p <- pNexts + , e <- eNexts + ] + let dedups = if pNow == eNow && pHere == eHere + then filter (\s -> (s ^. personRoom) < (s ^. elephantRoom)) nexts + -- else nexts + else filter (\s -> (s ^. personRoom) /= (s ^. elephantRoom)) nexts + -- let succStates = trace ("Succs: in " ++ (show state) ++ " out " ++ (show dedups)) (Q.fromList dedups) + let succStates = Q.fromList dedups + if isFF || (Q.null succStates) + then return $ Q.singleton (state & personTime .~ timeLimit & elephantTime .~ timeLimit) + else return succStates + + estimateBenefit here = do cave <- asks getCave timeLimit <- asks getTimeLimit - let timeRemaining = timeLimit - (timeElapsed + 2) + let timeRemaining = timeLimit - (timeOf here) cf <- currentFlow here - let closedValves = (cave `M.withoutKeys` (here ^. dOpenValves)) ^.. folded . flowRate - let sortedClosedValves = fmap sum $ chunksOf 2 $ sortOn Down closedValves + -- let closedValves = (cave `M.withoutKeys` (here ^. dOpenValves)) ^.. folded . flowRate + -- let sortedClosedValves = fmap sum $ chunksOf 2 $ {-# SCC estSort #-} sortOn Down closedValves + -- let sortedClosedValves = fmap sum $ chunksOf 2 $ reverse $ sort closedValves -- no significant improvement + sortedValves <- asks getSortedRooms + let opened = here ^. dOpenValves + let sortedClosedValves = fmap sum $ chunksOf 2 $ [(cave ! v) ^. flowRate | v <- sortedValves, v `S.notMember` opened] let otherValveFlows = sum $ zipWith (*) [timeRemaining, (timeRemaining - 2) .. 0] sortedClosedValves + -- let otherValveFlows = timeRemaining * (sum closedValves) -- 8 minute runtime rather than 1:50 return $ (cf * timeRemaining) + otherValveFlows @@ -152,8 +186,11 @@ main :: IO () main = do dataFileName <- getDataFileName text <- TIO.readFile dataFileName - let cave = successfulParse text + let expandedCave = successfulParse text -- print cave + -- print $ reachableFrom cave [Tunnel "AA" 0] S.empty [] + -- print $ compress cave + let cave = compress expandedCave print $ part1 cave print $ part2 cave @@ -164,10 +201,14 @@ main = -- part2 cave = runReader (searchCave "AA") (TimedCave cave 26) part1, part2 :: Cave -> Int +-- part1 :: Cave -> Int part1 cave = maybe 0 _benefit result - where result = runReader (searchCave "AA") (TimedCave cave 30) :: Maybe (Agendum SingleSearchState) + where result = runReader (searchCave "AA") (TimedCave cave 30 sortedRooms) :: Maybe (Agendum SingleSearchState) + sortedRooms = sortOn (\r -> Down $ (cave ! r) ^. flowRate ) $ M.keys $ M.filter (\r -> r ^. flowRate > 0) cave part2 cave = maybe 0 _benefit result - where result = runReader (searchCave "AA") (TimedCave cave 26) :: Maybe (Agendum DoubleSearchState) + where result = runReader (searchCave "AA") (TimedCave cave 26 sortedRooms) :: Maybe (Agendum DoubleSearchState) + sortedRooms = sortOn (\r -> Down $ (cave ! r) ^. flowRate ) $ M.keys $ M.filter (\r -> r ^. flowRate > 0) cave + -- sortedRooms = sortOn (\r -> Down $ (cave ! r) ^. flowRate ) $ M.keys cave searchCave :: SearchState s => String -> CaveContext (Maybe (Agendum s)) searchCave startRoom = @@ -177,13 +218,15 @@ searchCave startRoom = initAgenda :: SearchState s => String -> CaveContext (Agenda s) initAgenda startID = do let startState = emptySearchState startID - b <- estimateBenefit startState 0 + b <- estimateBenefit startState return $ P.singleton b Agendum { _current = startState, _trail = Q.empty, _trailBenefit = 0, _benefit = b} aStar :: SearchState s => Agenda s -> ExploredStates s -> CaveContext (Maybe (Agendum s)) aStar agenda closed -- | trace ("Peeping " ++ (show $ fst $ P.findMin agenda) ++ ": " ++ (show reached) ++ " <- " ++ (show $ toList $ Q.take 1 $ _trail $ currentAgendum) ++ " :: " ++ (show newAgenda)) False = undefined - -- | trace ("Peeping " ++ (show $ _current $ snd $ P.findMax agenda) ++ " : len " ++ (show $ Q.length $ _trail $ snd $ P.findMax agenda)) False = undefined + -- | trace ("Peeping " ++ (show $ _current $ snd $ P.findMax agenda) ++ " : foundFlow " ++ (show $ _trailBenefit $ snd $ P.findMax agenda)) False = undefined + -- | trace ("Peeping " ++ (show $ _current $ snd $ P.findMax agenda) ++ " : foundFlow " ++ (show $ _trailBenefit $ snd $ P.findMax agenda) ++ " : trail " ++ (show $ _trail $ snd $ P.findMax agenda) ++ " : closed " ++ (show closed)) False = undefined + -- | trace ("Peeping " ++ (show $ P.findMax agenda)) False = undefined | P.null agenda = return Nothing | otherwise = do let (_, currentAgendum) = P.findMax agenda @@ -191,15 +234,17 @@ aStar agenda closed nexts <- candidates currentAgendum closed let newAgenda = foldl' (\q a -> P.insert (_benefit a) a q) (P.deleteMax agenda) nexts -- let beamAgenda = P.fromDescList $ P.take 10000 newAgenda -- agenda beam width - let beamAgenda = P.fromDescList $ P.take 5000 newAgenda -- agenda beam width + -- let beamAgenda = P.fromDescList $ P.take 5000 newAgenda -- agenda beam width + -- let beamAgenda = P.fromDescList $ P.take 1000 newAgenda -- agenda beam width reachedGoal <- isGoal currentAgendum - let cl = (reached, currentAgendum ^. trailBenefit, Q.length $ currentAgendum ^. trail) + -- let cl = (reached, currentAgendum ^. trailBenefit, Q.length $ currentAgendum ^. trail) + let cl = (reached, currentAgendum ^. trailBenefit) if reachedGoal then return (Just currentAgendum) else if (cl `S.member` closed) then aStar (P.deleteMax agenda) closed - -- else aStar newAgenda (S.insert cl closed) - else aStar beamAgenda (S.insert cl closed) + else aStar newAgenda (S.insert cl closed) + -- else aStar beamAgenda (S.insert cl closed) candidates :: SearchState s => Agendum s -> ExploredStates s -> CaveContext (Q.Seq (Agendum s)) @@ -209,41 +254,65 @@ candidates agendum closed = let prevBenefit = agendum ^. trailBenefit succs <- successors candidate succAgs <- mapM (makeAgendum previous prevBenefit) succs - let nonloops = Q.filter (\s -> (s ^. current, s ^. trailBenefit, Q.length $ s ^. trail) `S.notMember` closed) succAgs + -- let nonloops = Q.filter (\s -> (s ^. current, s ^. trailBenefit, Q.length $ s ^. trail) `S.notMember` closed) succAgs + let nonloops = Q.filter (\s -> (s ^. current, s ^. trailBenefit) `S.notMember` closed) succAgs return nonloops -personSuccessor, openValveSuccessor, walkSuccessor :: RoomID -> S.Set RoomID -> CaveContext [(RoomID, S.Set RoomID)] -personSuccessor here opened = - do ovs <- openValveSuccessor here opened - ws <- walkSuccessor here opened - return (ovs ++ ws) -openValveSuccessor here opened - | here `S.member` opened = return [] - | otherwise = return [(here, S.insert here opened)] - -walkSuccessor here opened = - do cave <- asks getCave - let neighbours = (cave ! here) ^. tunnels - return [(n, opened) | n <- neighbours] +agentSuccessor :: Int -> S.Set RoomID -> Int -> RoomID -> CaveContext [SingleSearchState] +agentSuccessor now opened aTime here + | aTime /= now = return [SingleSearchState { _currentRoom = here, _currentTime = aTime, _sOpenValves = opened }] + | otherwise = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + let remaining = S.toList $ S.filter (\t -> (t ^. tunnelTo) `S.notMember` opened) ((cave ! here) ^. tunnels) + let moves = [ SingleSearchState + { _currentRoom = (t ^. tunnelTo) + , _currentTime = now + (t ^. tunnelLength) + , _sOpenValves = opened + } + | t <- remaining + , now + (t ^. tunnelLength) <= timeLimit + ] + let opens = if here `S.notMember` opened && (cave ! here) ^. flowRate > 0 + then [SingleSearchState { _currentRoom = here, _currentTime = aTime + 1, _sOpenValves = S.insert here opened }] + else [] + -- let nexts = moves ++ opens + let nexts = if null opens then moves else opens + let nexts' = if null nexts + then [ SingleSearchState + { _currentRoom = here + , _currentTime = timeLimit + , _sOpenValves = opened + } ] + else nexts + return nexts' makeAgendum :: SearchState s => Q.Seq s -> Int -> s -> CaveContext (Agendum s) makeAgendum previous prevBenefit newState = - do predicted <- estimateBenefit newState (Q.length previous) - cf <- currentFlow newState + do predicted <- estimateBenefit newState -- (Q.length previous) + -- cf <- currentFlow newState + oldFlow <- lastFlow previous (timeOf newState) let newTrail = previous |> newState - let incurred = prevBenefit + cf + let incurred = prevBenefit + oldFlow return Agendum { _current = newState , _trail = newTrail , _trailBenefit = incurred , _benefit = incurred + predicted } +lastFlow :: SearchState s => Q.Seq s -> Int -> CaveContext Int +lastFlow Q.Empty _ = return 0 +lastFlow (_ :|> previous) newTime = + do cf <- currentFlow previous + let dt = newTime - (timeOf previous) + return (cf * dt) isGoal :: SearchState s => Agendum s -> CaveContext Bool isGoal agendum = do timeLimit <- asks getTimeLimit - return $ Q.length (agendum ^. trail) == (timeLimit - 1) + let s = agendum ^. current + return $ (timeOf s) == timeLimit isFullFlow :: SearchState s => s -> CaveContext Bool isFullFlow state = @@ -252,21 +321,40 @@ isFullFlow state = let ff = sumOf (folded . flowRate) cave return (cf == ff) +compress :: Cave -> Cave +compress cave = M.mapWithKey (compressRoom cave) cave + +compressRoom :: Cave -> RoomID -> Room -> Room +compressRoom cave here room = room & tunnels .~ t' + where t' = reachableFrom cave [Tunnel here 0] S.empty S.empty + +reachableFrom :: Cave -> [Tunnel] -> S.Set RoomID -> S.Set Tunnel -> S.Set Tunnel +reachableFrom _ [] _ routes = routes +reachableFrom cave (tunnel@(Tunnel here len):boundary) found routes + | here `S.member` found = reachableFrom cave boundary found routes + | otherwise = reachableFrom cave (boundary ++ (S.toList legs)) (S.insert here found) routes' + where exits = (cave ! here) ^. tunnels + exits' = S.filter (\t -> (t ^. tunnelTo) `S.notMember` found) exits + legs = S.map (\t -> t & tunnelLength .~ (len + 1)) exits' + routes' = if (len == 0) || ((cave ! here) ^. flowRate) == 0 + then routes + else S.insert tunnel routes + -- Parse the input file caveP :: Parser Cave valveP :: Parser (RoomID, Room) roomP :: Parser Room -tunnelsP :: Parser [RoomID] -turnnelTextP :: Parser Text +tunnelsP :: Parser (S.Set Tunnel) +tunnelTextP :: Parser Text caveP = M.fromList <$> valveP `sepBy` endOfLine valveP = (,) <$> ("Valve " *> (many1 letter)) <*> roomP -roomP = roomify <$> (" has flow rate=" *> decimal) <*> (turnnelTextP *> tunnelsP) - where roomify v ts = Room {_flowRate = v, _tunnels = ts } -tunnelsP = (many1 letter) `sepBy` ", " -turnnelTextP = "; tunnels lead to valves " <|> "; tunnel leads to valve " +roomP = Room <$> (" has flow rate=" *> decimal) <*> (tunnelTextP *> tunnelsP) + -- where roomify v ts = Room {flowRate = v, tunnels = ts } +tunnelsP = (S.fromList . (fmap (flip Tunnel 1))) <$> (many1 letter) `sepBy` ", " +tunnelTextP = "; tunnels lead to valves " <|> "; tunnel leads to valve " successfulParse :: Text -> Cave successfulParse input = diff --git a/advent16/MainBeam.hs b/advent16/MainBeam.hs new file mode 100644 index 0000000..f82731c --- /dev/null +++ b/advent16/MainBeam.hs @@ -0,0 +1,362 @@ +-- Writeup at https://work.njae.me.uk/2022/12/17/advent-of-code-2022-day-16/ + +-- import Debug.Trace + +import AoC +import Data.Text (Text) +import qualified Data.Text.IO as TIO +import Data.Attoparsec.Text hiding (take, D) +import Control.Applicative +import qualified Data.PQueue.Prio.Max as P +import qualified Data.Set as S +import qualified Data.Sequence as Q +import qualified Data.Map.Strict as M +import Data.Map.Strict ((!)) +-- import Data.Sequence ((|>), Seq((:|>)), ViewR ((:>))) +import Data.Sequence ( (|>), Seq((:|>)) ) +import Data.List +import Data.List.Split (chunksOf) +import Data.Ord +import Control.Monad.Reader +import Control.Lens hiding ((<|), (|>), (:>), (:<), indices) + + +type RoomID = String + +data Tunnel = Tunnel { _tunnelTo :: RoomID, _tunnelLength :: Int} + deriving (Eq, Show, Ord) +makeLenses ''Tunnel + +data Room = Room + { _flowRate :: Int + , _tunnels :: S.Set Tunnel + } deriving (Eq, Show, Ord) +makeLenses ''Room + +type Cave = M.Map RoomID Room +data TimedCave = TimedCave { getCave :: Cave, getTimeLimit :: Int , getSortedRooms :: [RoomID]} + +type CaveContext = Reader TimedCave + +data SingleSearchState = SingleSearchState + { _currentRoom :: RoomID + , _currentTime :: Int + , _sOpenValves :: S.Set RoomID + } deriving (Eq, Show, Ord) +makeLenses ''SingleSearchState + +data DoubleSearchState = DoubleSearchState + { _personRoom :: RoomID + , _personTime :: Int + , _elephantRoom :: RoomID + , _elephantTime :: Int + , _dOpenValves :: S.Set RoomID + } deriving (Eq, Show, Ord) +makeLenses ''DoubleSearchState + +data Agendum s = + Agendum { _current :: s + , _trail :: Q.Seq s + , _trailBenefit :: Int + , _benefit :: Int + } deriving (Show, Eq, Ord) +makeLenses ''Agendum + +type Agenda s = P.MaxPQueue Int (Agendum s) + +-- state, total flowed so far +type ExploredStates s = S.Set (s, Int) + + +class (Eq s, Ord s, Show s) => SearchState s where + emptySearchState :: RoomID -> s + currentFlow :: s -> CaveContext Int + timeOf :: s -> Int + successors :: s -> CaveContext (Q.Seq s) + -- estimateBenefit :: s -> Int -> CaveContext Int + estimateBenefit :: s -> CaveContext Int + +instance SearchState SingleSearchState where + emptySearchState startID = SingleSearchState + { _currentRoom = startID + , _currentTime = 0 + , _sOpenValves = S.empty + } + + currentFlow state = + do cave <- asks getCave + let valves = state ^. sOpenValves + let presentRooms = cave `M.restrictKeys` valves + return $ sumOf (folded . flowRate) presentRooms + + timeOf state = state ^. currentTime + + successors state = + do isFF <- isFullFlow state + -- cave <- asks getCave + timeLimit <- asks getTimeLimit + let here = state ^. currentRoom + let opened = state ^. sOpenValves + let now = state ^. currentTime + succs <- agentSuccessor now opened now here + let succStates = Q.fromList succs + if isFF || (Q.null succStates) + then return $ Q.singleton (state & currentTime .~ timeLimit) + else return succStates + + estimateBenefit here = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + let timeRemaining = timeLimit - (timeOf here) + cf <- currentFlow here + -- let closedValves = (cave `M.withoutKeys` (here ^. sOpenValves)) ^.. folded . flowRate + -- let sortedClosedValves = sortOn Down closedValves + sortedValves <- asks getSortedRooms + let opened = here ^. sOpenValves + let sortedClosedValves = [(cave ! v) ^. flowRate | v <- sortedValves, v `S.notMember` opened] + let otherValveFlows = sum $ zipWith (*) [timeRemaining, (timeRemaining - 2) .. 0] sortedClosedValves + return $ (cf * timeRemaining) + otherValveFlows + + +instance SearchState DoubleSearchState where + emptySearchState startID = DoubleSearchState + { _personRoom = startID + , _personTime = 0 + , _elephantRoom = startID + , _elephantTime = 0 + , _dOpenValves = S.empty + } + + currentFlow state = + do cave <- asks getCave + let valves = S.toList $ state ^. dOpenValves + return $ sum $ fmap (\v -> (cave ! v) ^. flowRate) valves + -- let presentRooms = cave `M.restrictKeys` valves + -- return $ sumOf (folded . flowRate) presentRooms + + timeOf state = min (state ^. personTime) (state ^. elephantTime) + + successors state = + do isFF <- isFullFlow state + -- cave <- asks getCave + timeLimit <- asks getTimeLimit + let opened = state ^. dOpenValves + let pNow = state ^. personTime + let eNow = state ^. elephantTime + let now = min pNow eNow + let pHere = state ^. personRoom + let eHere = state ^. elephantRoom + pNexts <- agentSuccessor now opened pNow pHere + eNexts <- agentSuccessor now opened eNow eHere + let nexts = [ state & personRoom .~ (p ^. currentRoom) + & personTime .~ (p ^. currentTime) + & elephantRoom .~ (e ^. currentRoom) + & elephantTime .~ (e ^. currentTime) + & dOpenValves %~ (S.union (p ^. sOpenValves) . S.union (e ^. sOpenValves)) + | p <- pNexts + , e <- eNexts + ] + let dedups = if pNow == eNow && pHere == eHere + then filter (\s -> (s ^. personRoom) < (s ^. elephantRoom)) nexts + -- else nexts + else filter (\s -> (s ^. personRoom) /= (s ^. elephantRoom)) nexts + -- let succStates = trace ("Succs: in " ++ (show state) ++ " out " ++ (show dedups)) (Q.fromList dedups) + let succStates = Q.fromList dedups + if isFF || (Q.null succStates) + then return $ Q.singleton (state & personTime .~ timeLimit & elephantTime .~ timeLimit) + else return succStates + + estimateBenefit here = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + let timeRemaining = timeLimit - (timeOf here) + cf <- currentFlow here + -- let closedValves = (cave `M.withoutKeys` (here ^. dOpenValves)) ^.. folded . flowRate + -- let sortedClosedValves = fmap sum $ chunksOf 2 $ {-# SCC estSort #-} sortOn Down closedValves + -- let sortedClosedValves = fmap sum $ chunksOf 2 $ reverse $ sort closedValves -- no significant improvement + sortedValves <- asks getSortedRooms + let opened = here ^. dOpenValves + let sortedClosedValves = fmap sum $ chunksOf 2 $ [(cave ! v) ^. flowRate | v <- sortedValves, v `S.notMember` opened] + let otherValveFlows = sum $ zipWith (*) [timeRemaining, (timeRemaining - 2) .. 0] sortedClosedValves + -- let otherValveFlows = timeRemaining * (sum closedValves) -- 8 minute runtime rather than 1:50 + return $ (cf * timeRemaining) + otherValveFlows + + +main :: IO () +main = + do dataFileName <- getDataFileName + text <- TIO.readFile dataFileName + let expandedCave = successfulParse text + -- print cave + -- print $ reachableFrom cave [Tunnel "AA" 0] S.empty [] + -- print $ compress cave + let cave = compress expandedCave + print $ part1 cave + print $ part2 cave + +-- part1 :: Cave -> Maybe (Agendum SingleSearchState) +-- part1 cave = runReader (searchCave "AA") (TimedCave cave 30) + +-- part2 :: Cave -> Maybe (Agendum DoubleSearchState) +-- part2 cave = runReader (searchCave "AA") (TimedCave cave 26) + +part1, part2 :: Cave -> Int +-- part1 :: Cave -> Int +part1 cave = maybe 0 _benefit result + where result = runReader (searchCave "AA") (TimedCave cave 30 sortedRooms) :: Maybe (Agendum SingleSearchState) + sortedRooms = sortOn (\r -> Down $ (cave ! r) ^. flowRate ) $ M.keys $ M.filter (\r -> r ^. flowRate > 0) cave +part2 cave = maybe 0 _benefit result + where result = runReader (searchCave "AA") (TimedCave cave 26 sortedRooms) :: Maybe (Agendum DoubleSearchState) + sortedRooms = sortOn (\r -> Down $ (cave ! r) ^. flowRate ) $ M.keys $ M.filter (\r -> r ^. flowRate > 0) cave + -- sortedRooms = sortOn (\r -> Down $ (cave ! r) ^. flowRate ) $ M.keys cave + +searchCave :: SearchState s => String -> CaveContext (Maybe (Agendum s)) +searchCave startRoom = + do agenda <- initAgenda startRoom + aStar agenda S.empty + +initAgenda :: SearchState s => String -> CaveContext (Agenda s) +initAgenda startID = + do let startState = emptySearchState startID + b <- estimateBenefit startState + return $ P.singleton b Agendum { _current = startState, _trail = Q.empty, _trailBenefit = 0, _benefit = b} + +aStar :: SearchState s => Agenda s -> ExploredStates s -> CaveContext (Maybe (Agendum s)) +aStar agenda closed + -- | trace ("Peeping " ++ (show $ fst $ P.findMin agenda) ++ ": " ++ (show reached) ++ " <- " ++ (show $ toList $ Q.take 1 $ _trail $ currentAgendum) ++ " :: " ++ (show newAgenda)) False = undefined + -- | trace ("Peeping " ++ (show $ _current $ snd $ P.findMax agenda) ++ " : foundFlow " ++ (show $ _trailBenefit $ snd $ P.findMax agenda)) False = undefined + -- | trace ("Peeping " ++ (show $ P.findMax agenda)) False = undefined + | P.null agenda = return Nothing + | otherwise = + do let (_, currentAgendum) = P.findMax agenda + let reached = currentAgendum ^. current + nexts <- candidates currentAgendum closed + let newAgenda = foldl' (\q a -> P.insert (_benefit a) a q) (P.deleteMax agenda) nexts + -- let beamAgenda = P.fromDescList $ P.take 10000 newAgenda -- agenda beam width + -- let beamAgenda = P.fromDescList $ P.take 5000 newAgenda -- agenda beam width + let beamAgenda = P.fromDescList $ P.take 1000 newAgenda -- agenda beam width + reachedGoal <- isGoal currentAgendum + -- let cl = (reached, currentAgendum ^. trailBenefit, Q.length $ currentAgendum ^. trail) + let cl = (reached, currentAgendum ^. trailBenefit) + if reachedGoal + then return (Just currentAgendum) + else if (cl `S.member` closed) + then aStar (P.deleteMax agenda) closed + -- else aStar newAgenda (S.insert cl closed) + else aStar beamAgenda (S.insert cl closed) + + +candidates :: SearchState s => Agendum s -> ExploredStates s -> CaveContext (Q.Seq (Agendum s)) +candidates agendum closed = + do let candidate = agendum ^. current + let previous = agendum ^. trail + let prevBenefit = agendum ^. trailBenefit + succs <- successors candidate + succAgs <- mapM (makeAgendum previous prevBenefit) succs + -- let nonloops = Q.filter (\s -> (s ^. current, s ^. trailBenefit, Q.length $ s ^. trail) `S.notMember` closed) succAgs + let nonloops = Q.filter (\s -> (s ^. current, s ^. trailBenefit) `S.notMember` closed) succAgs + return nonloops + + +agentSuccessor :: Int -> S.Set RoomID -> Int -> RoomID -> CaveContext [SingleSearchState] +agentSuccessor now opened aTime here + | aTime /= now = return [SingleSearchState { _currentRoom = here, _currentTime = aTime, _sOpenValves = opened }] + | otherwise = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + let remaining = S.toList $ S.filter (\t -> (t ^. tunnelTo) `S.notMember` opened) ((cave ! here) ^. tunnels) + let moves = [ SingleSearchState + { _currentRoom = (t ^. tunnelTo) + , _currentTime = now + (t ^. tunnelLength) + , _sOpenValves = opened + } + | t <- remaining + , now + (t ^. tunnelLength) <= timeLimit + ] + let opens = if here `S.notMember` opened && (cave ! here) ^. flowRate > 0 + then [SingleSearchState { _currentRoom = here, _currentTime = aTime + 1, _sOpenValves = S.insert here opened }] + else [] + -- let nexts = moves ++ opens + let nexts = if null opens then moves else opens + let nexts' = if null nexts + then [ SingleSearchState + { _currentRoom = here + , _currentTime = timeLimit + , _sOpenValves = opened + } ] + else nexts + return nexts' + +makeAgendum :: SearchState s => Q.Seq s -> Int -> s -> CaveContext (Agendum s) +makeAgendum previous prevBenefit newState = + do predicted <- estimateBenefit newState -- (Q.length previous) + -- cf <- currentFlow newState + oldFlow <- lastFlow previous (timeOf newState) + let newTrail = previous |> newState + let incurred = prevBenefit + oldFlow + return Agendum { _current = newState + , _trail = newTrail + , _trailBenefit = incurred + , _benefit = incurred + predicted + } + +lastFlow :: SearchState s => Q.Seq s -> Int -> CaveContext Int +lastFlow Q.Empty _ = return 0 +lastFlow (_ :|> previous) newTime = + do cf <- currentFlow previous + let dt = newTime - (timeOf previous) + return (cf * dt) + +isGoal :: SearchState s => Agendum s -> CaveContext Bool +isGoal agendum = + do timeLimit <- asks getTimeLimit + let s = agendum ^. current + return $ (timeOf s) == timeLimit + +isFullFlow :: SearchState s => s -> CaveContext Bool +isFullFlow state = + do cave <- asks getCave + cf <- currentFlow state + let ff = sumOf (folded . flowRate) cave + return (cf == ff) + +compress :: Cave -> Cave +compress cave = M.mapWithKey (compressRoom cave) cave + +compressRoom :: Cave -> RoomID -> Room -> Room +compressRoom cave here room = room & tunnels .~ t' + where t' = reachableFrom cave [Tunnel here 0] S.empty S.empty + +reachableFrom :: Cave -> [Tunnel] -> S.Set RoomID -> S.Set Tunnel -> S.Set Tunnel +reachableFrom _ [] _ routes = routes +reachableFrom cave (tunnel@(Tunnel here len):boundary) found routes + | here `S.member` found = reachableFrom cave boundary found routes + | otherwise = reachableFrom cave (boundary ++ (S.toList legs)) (S.insert here found) routes' + where exits = (cave ! here) ^. tunnels + exits' = S.filter (\t -> (t ^. tunnelTo) `S.notMember` found) exits + legs = S.map (\t -> t & tunnelLength .~ (len + 1)) exits' + routes' = if (len == 0) || ((cave ! here) ^. flowRate) == 0 + then routes + else S.insert tunnel routes + + +-- Parse the input file + +caveP :: Parser Cave +valveP :: Parser (RoomID, Room) +roomP :: Parser Room +tunnelsP :: Parser (S.Set Tunnel) +tunnelTextP :: Parser Text + +caveP = M.fromList <$> valveP `sepBy` endOfLine +valveP = (,) <$> ("Valve " *> (many1 letter)) <*> roomP +roomP = Room <$> (" has flow rate=" *> decimal) <*> (tunnelTextP *> tunnelsP) + -- where roomify v ts = Room {flowRate = v, tunnels = ts } +tunnelsP = (S.fromList . (fmap (flip Tunnel 1))) <$> (many1 letter) `sepBy` ", " +tunnelTextP = "; tunnels lead to valves " <|> "; tunnel leads to valve " + +successfulParse :: Text -> Cave +successfulParse input = + case parseOnly caveP input of + Left _err -> M.empty -- TIO.putStr $ T.pack $ parseErrorPretty err + Right cave -> cave \ No newline at end of file diff --git a/advent16/MainCustomClosed.hs b/advent16/MainCustomClosed.hs new file mode 100644 index 0000000..63fdf60 --- /dev/null +++ b/advent16/MainCustomClosed.hs @@ -0,0 +1,401 @@ +-- Writeup at https://work.njae.me.uk/2022/12/17/advent-of-code-2022-day-16/ + +import Debug.Trace + +import AoC +import Data.Text (Text) +import qualified Data.Text.IO as TIO +import Data.Attoparsec.Text hiding (take, D) +import Control.Applicative +import qualified Data.PQueue.Prio.Max as P +import qualified Data.Set as S +import qualified Data.Sequence as Q +import qualified Data.Map.Strict as M +import Data.Map.Strict ((!)) +-- import Data.Sequence ((|>), Seq((:|>)), ViewR ((:>))) +import Data.Sequence ( (<|), (|>), Seq((:|>)) ) +import Data.List +import Data.List.Split (chunksOf) +import Data.Ord +import Control.Monad.Reader +import Control.Lens hiding ((<|), (|>), (:>), (:<), indices) + + +type RoomID = String + +data Tunnel = Tunnel { _tunnelTo :: RoomID, _tunnelLength :: Int} + deriving (Eq, Show, Ord) +makeLenses ''Tunnel + +data Room = Room + { _flowRate :: Int + , _tunnels :: S.Set Tunnel + } deriving (Eq, Show, Ord) +makeLenses ''Room + +type Cave = M.Map RoomID Room +data TimedCave = TimedCave { getCave :: Cave, getTimeLimit :: Int , getSortedRooms :: [RoomID]} + +type CaveContext = Reader TimedCave + +data SingleSearchState = SingleSearchState + { _currentRoom :: RoomID + , _currentTime :: Int + , _sOpenValves :: [RoomID] + } deriving (Eq, Show, Ord) +makeLenses ''SingleSearchState + +data DoubleSearchState = DoubleSearchState + { _personRoom :: RoomID + , _personTime :: Int + , _elephantRoom :: RoomID + , _elephantTime :: Int + , _dOpenValves :: [RoomID] + } deriving (Eq, Show, Ord) +makeLenses ''DoubleSearchState + +data Agendum s = + Agendum { _current :: s + , _trail :: Q.Seq s + , _trailBenefit :: Int + , _benefit :: Int + } deriving (Show, Eq, Ord) +makeLenses ''Agendum + +type Agenda s = P.MaxPQueue Int (Agendum s) + +-- state, total flowed so far +-- type ExploredStates s = S.Set (s, Int) + + +class (Eq s, Ord s, Show s) => SearchState s where + emptySearchState :: RoomID -> s + currentFlow :: s -> CaveContext Int + timeOf :: s -> Int + successors :: s -> CaveContext (Q.Seq s) + -- estimateBenefit :: s -> Int -> CaveContext Int + estimateBenefit :: s -> CaveContext Int + + data ExploredStateKey s + -- type ExploredStates s + + mkExploredKey :: s -> (ExploredStateKey s) + +-- type ExploredStates s = M.Map (ExploredStateKey s) Int -- room/valves to time +type ExploredStates s = S.Set ((ExploredStateKey s), Int) -- room & valves, trail benefit + +instance SearchState SingleSearchState where + emptySearchState startID = SingleSearchState + { _currentRoom = startID + , _currentTime = 0 + , _sOpenValves = [] + } + + data ExploredStateKey SingleSearchState = SingleExploredStateKey RoomID [RoomID] -- current room and open valves + deriving (Show, Eq, Ord) + + mkExploredKey s = SingleExploredStateKey (s ^. currentRoom) (s ^. sOpenValves) + + currentFlow state = + do cave <- asks getCave + let valves = state ^. sOpenValves + let presentRooms = cave `M.restrictKeys` (S.fromList valves) + -- let presentRooms = M.filter (\v -> v `elem` valves) cave + return $ sumOf (folded . flowRate) presentRooms + + timeOf state = state ^. currentTime + + successors state = + do isFF <- isFullFlow state + -- cave <- asks getCave + timeLimit <- asks getTimeLimit + let here = state ^. currentRoom + let opened = state ^. sOpenValves + let now = state ^. currentTime + succs <- agentSuccessor now opened now here + let succStates = Q.fromList succs + if isFF || (Q.null succStates) + then return $ Q.singleton (state & currentTime .~ timeLimit) + else return succStates + + estimateBenefit here = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + let timeRemaining = timeLimit - (timeOf here) + cf <- currentFlow here + -- let closedValves = (cave `M.withoutKeys` (here ^. sOpenValves)) ^.. folded . flowRate + -- let sortedClosedValves = sortOn Down closedValves + sortedValves <- asks getSortedRooms + let opened = here ^. sOpenValves + let sortedClosedValves = [(cave ! v) ^. flowRate | v <- sortedValves, v `notElem` opened] + let otherValveFlows = sum $ zipWith (*) [timeRemaining, (timeRemaining - 2) .. 0] sortedClosedValves + return $ (cf * timeRemaining) + otherValveFlows + + +instance SearchState DoubleSearchState where + emptySearchState startID = DoubleSearchState + { _personRoom = startID + , _personTime = 0 + , _elephantRoom = startID + , _elephantTime = 0 + , _dOpenValves = [] + } + + data ExploredStateKey DoubleSearchState = DoubleExploredStateKey RoomID RoomID [RoomID] -- current room (person, elephant) and open valves + -- deriving (Show) + deriving (Show, Eq, Ord) + -- type ExploredStates DoubleSearchState = M.Map (DoubleExploredStateKey DoubleSearchState) Int -- room/valves to time + + mkExploredKey s = DoubleExploredStateKey minRoom maxRoom (s ^. dOpenValves) + where minRoom = min (s ^. personRoom) (s ^. elephantRoom) + maxRoom = max (s ^. personRoom) (s ^. elephantRoom) + + currentFlow state = + do cave <- asks getCave + -- let valves = S.toList $ state ^. dOpenValves + let valves = state ^. dOpenValves + return $ sum $ fmap (\v -> (cave ! v) ^. flowRate) valves + -- let presentRooms = cave `M.restrictKeys` valves + -- return $ sumOf (folded . flowRate) presentRooms + + timeOf state = min (state ^. personTime) (state ^. elephantTime) + + successors state = + do isFF <- isFullFlow state + -- cave <- asks getCave + timeLimit <- asks getTimeLimit + let opened = state ^. dOpenValves + let pNow = state ^. personTime + let eNow = state ^. elephantTime + let now = min pNow eNow + let pHere = state ^. personRoom + let eHere = state ^. elephantRoom + pNexts <- agentSuccessor now opened pNow pHere + eNexts <- agentSuccessor now opened eNow eHere + let nexts = [ state & personRoom .~ (p ^. currentRoom) + & personTime .~ (p ^. currentTime) + & elephantRoom .~ (e ^. currentRoom) + & elephantTime .~ (e ^. currentTime) + -- & dOpenValves %~ (S.union (p ^. sOpenValves) . S.union (e ^. sOpenValves)) + & dOpenValves .~ (union (union opened (p ^. sOpenValves)) (e ^. sOpenValves)) + | p <- pNexts + , e <- eNexts + ] + let dedups = if pNow == eNow && pHere == eHere + then filter (\s -> (s ^. personRoom) < (s ^. elephantRoom)) nexts + else nexts + -- let succStates = trace ("Succs: in " ++ (show state) ++ " out " ++ (show dedups)) (Q.fromList dedups) + let succStates = Q.fromList dedups + if isFF || (Q.null succStates) + then return $ Q.singleton (state & personTime .~ timeLimit & elephantTime .~ timeLimit) + else return succStates + + estimateBenefit here = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + let timeRemaining = timeLimit - (timeOf here) + cf <- currentFlow here + -- let closedValves = (cave `M.withoutKeys` (here ^. dOpenValves)) ^.. folded . flowRate + -- let sortedClosedValves = fmap sum $ chunksOf 2 $ {-# SCC estSort #-} sortOn Down closedValves + -- let sortedClosedValves = fmap sum $ chunksOf 2 $ reverse $ sort closedValves -- no significant improvement + sortedValves <- asks getSortedRooms + let opened = here ^. dOpenValves + let sortedClosedValves = fmap sum $ chunksOf 2 $ [(cave ! v) ^. flowRate | v <- sortedValves, v `notElem` opened] + let otherValveFlows = sum $ zipWith (*) [timeRemaining, (timeRemaining - 2) .. 0] sortedClosedValves + -- let otherValveFlows = timeRemaining * (sum closedValves) -- 8 minute runtime rather than 1:50 + return $ (cf * timeRemaining) + otherValveFlows + +-- instance Eq (ExploredStateKey DoubleSearchState) where +-- (DoubleExploredStateKey r1a r1b v1) == (DoubleExploredStateKey r2a r2b v2) = +-- -- ((r1a == r2a && r1b == r2b) || (r1a == r2b && r1b == r2a)) && v1 == v2 +-- ((min r1a r1b), (max r1a r1b), v1) == ((min r2a r2b), (max r2a r2b), v2) +-- -- data instance Ord DoubleExploredStateKey where +-- instance Ord (ExploredStateKey DoubleSearchState) where +-- (DoubleExploredStateKey r1a r1b v1) `compare` (DoubleExploredStateKey r2a r2b v2) = +-- ((min r1a r1b), (max r1a r1b), v1) `compare` ((min r2a r2b), (max r2a r2b), v2) + + +main :: IO () +main = + do dataFileName <- getDataFileName + text <- TIO.readFile dataFileName + let expandedCave = successfulParse text + -- print cave + -- print $ reachableFrom cave [Tunnel "AA" 0] S.empty [] + -- print $ compress cave + let cave = compress expandedCave + print $ part1 cave + print $ part2 cave + +-- part1 :: Cave -> Maybe (Agendum SingleSearchState) +-- part1 cave = runReader (searchCave "AA") (TimedCave cave 30) + +-- part2 :: Cave -> Maybe (Agendum DoubleSearchState) +-- part2 cave = runReader (searchCave "AA") (TimedCave cave 26) + +part1, part2 :: Cave -> Int +-- part1 :: Cave -> Int +part1 cave = maybe 0 _benefit result +-- part1 cave = result + where result = runReader (searchCave "AA") (TimedCave cave 30 sortedRooms) :: Maybe (Agendum SingleSearchState) + sortedRooms = sortOn (\r -> Down $ (cave ! r) ^. flowRate ) $ M.keys $ M.filter (\r -> r ^. flowRate > 0) cave +part2 cave = maybe 0 _benefit result +-- part2 cave = result + where result = runReader (searchCave "AA") (TimedCave cave 26 sortedRooms) :: Maybe (Agendum DoubleSearchState) + sortedRooms = sortOn (\r -> Down $ (cave ! r) ^. flowRate ) $ M.keys $ M.filter (\r -> r ^. flowRate > 0) cave + -- sortedRooms = sortOn (\r -> Down $ (cave ! r) ^. flowRate ) $ M.keys cave + +searchCave :: ((Ord (ExploredStateKey s)), (Show (ExploredStateKey s)), SearchState s) => String -> CaveContext (Maybe (Agendum s)) +searchCave startRoom = + do agenda <- initAgenda startRoom + aStar agenda S.empty + +initAgenda :: ((Ord (ExploredStateKey s)), (Show (ExploredStateKey s)), SearchState s) => String -> CaveContext (Agenda s) +initAgenda startID = + do let startState = emptySearchState startID + b <- estimateBenefit startState + return $ P.singleton b Agendum { _current = startState, _trail = Q.empty, _trailBenefit = 0, _benefit = b} + +aStar :: ((Ord (ExploredStateKey s)), (Show (ExploredStateKey s)), SearchState s) => Agenda s -> ExploredStates s -> CaveContext (Maybe (Agendum s)) +aStar agenda closed + -- | trace ("Peeping " ++ (show $ fst $ P.findMin agenda) ++ ": " ++ (show reached) ++ " <- " ++ (show $ toList $ Q.take 1 $ _trail $ currentAgendum) ++ " :: " ++ (show newAgenda)) False = undefined + -- | trace ("Peeping " ++ (show $ _current $ snd $ P.findMax agenda) ++ " : foundFlow " ++ (show $ _trailBenefit $ snd $ P.findMax agenda) ++ " : trail " ++ (show $ _trail $ snd $ P.findMax agenda) ++ " : closed " ++ (show closed)) False = undefined + -- | trace ("Peeping " ++ (show $ P.findMax agenda)) False = undefined + | P.null agenda = return Nothing + | otherwise = + do let (_, currentAgendum) = P.findMax agenda + let reached = currentAgendum ^. current + nexts <- candidates currentAgendum closed + let newAgenda = foldl' (\q a -> P.insert (_benefit a) a q) (P.deleteMax agenda) nexts + -- let beamAgenda = P.fromDescList $ P.take 10000 newAgenda -- agenda beam width + -- let beamAgenda = P.fromDescList $ P.take 5000 newAgenda -- agenda beam width + -- let beamAgenda = P.fromDescList $ P.take 1000 newAgenda -- agenda beam width + reachedGoal <- isGoal currentAgendum + -- let cl = (reached, currentAgendum ^. trailBenefit, Q.length $ currentAgendum ^. trail) + -- let cl = (reached, currentAgendum ^. trailBenefit) + let cl = (mkExploredKey reached, currentAgendum ^. trailBenefit) + if reachedGoal + then return (Just currentAgendum) + else if (cl `elem` closed) + then aStar (P.deleteMax agenda) closed + else aStar newAgenda (S.insert cl closed) + + +candidates :: ((Ord (ExploredStateKey s)), SearchState s) => Agendum s -> ExploredStates s -> CaveContext (Q.Seq (Agendum s)) +candidates agendum closed = + do let candidate = agendum ^. current + let previous = agendum ^. trail + let prevBenefit = agendum ^. trailBenefit + succs <- successors candidate + succAgs <- mapM (makeAgendum previous prevBenefit) succs + -- let nonloops = Q.filter (\s -> (s ^. current, s ^. trailBenefit, Q.length $ s ^. trail) `S.notMember` closed) succAgs + -- let nonloops = Q.filter (\s -> (s ^. current, s ^. trailBenefit) `S.notMember` closed) succAgs + let nonloops = Q.filter (\l -> ((mkExploredKey (l ^. current)), l ^. trailBenefit) `notElem` closed) succAgs + return nonloops + + +agentSuccessor :: Int -> [RoomID] -> Int -> RoomID -> CaveContext [SingleSearchState] +agentSuccessor now opened aTime here + | aTime /= now = return [SingleSearchState { _currentRoom = here, _currentTime = aTime, _sOpenValves = opened }] + | otherwise = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + -- let remaining = S.toList $ S.filter (\t -> (t ^. tunnelTo) `S.notMember` opened) ((cave ! here) ^. tunnels) + let remaining = [ t + | t <- (S.toList ((cave ! here) ^. tunnels)) + , (t ^. tunnelTo) `notElem` opened + ] + let moves = [ SingleSearchState + { _currentRoom = (t ^. tunnelTo) + , _currentTime = now + (t ^. tunnelLength) + , _sOpenValves = opened + } + | t <- remaining + , now + (t ^. tunnelLength) <= timeLimit + ] + let moves' = ( SingleSearchState + { _currentRoom = here + , _currentTime = timeLimit + , _sOpenValves = opened + } + : moves) + let opens = if here `notElem` opened && (cave ! here) ^. flowRate > 0 + then [SingleSearchState { _currentRoom = here, _currentTime = aTime + 1, _sOpenValves = opened ++ [here] }] + else [] + -- let nexts = moves ++ opens + let nexts = if null opens then moves' else opens + return nexts + +makeAgendum :: SearchState s => Q.Seq s -> Int -> s -> CaveContext (Agendum s) +makeAgendum previous prevBenefit newState = + do predicted <- estimateBenefit newState -- (Q.length previous) + -- cf <- currentFlow newState + oldFlow <- lastFlow previous (timeOf newState) + let newTrail = previous |> newState + let incurred = prevBenefit + oldFlow + return Agendum { _current = newState + , _trail = newTrail + , _trailBenefit = incurred + , _benefit = incurred + predicted + } + +lastFlow :: SearchState s => Q.Seq s -> Int -> CaveContext Int +lastFlow Q.Empty _ = return 0 +lastFlow (_ :|> previous) newTime = + do cf <- currentFlow previous + let dt = newTime - (timeOf previous) + return (cf * dt) + +isGoal :: SearchState s => Agendum s -> CaveContext Bool +isGoal agendum = + do timeLimit <- asks getTimeLimit + let s = agendum ^. current + return $ (timeOf s) == timeLimit + +isFullFlow :: SearchState s => s -> CaveContext Bool +isFullFlow state = + do cave <- asks getCave + cf <- currentFlow state + let ff = sumOf (folded . flowRate) cave + return (cf == ff) + +compress :: Cave -> Cave +compress cave = M.mapWithKey (compressRoom cave) cave + +compressRoom :: Cave -> RoomID -> Room -> Room +compressRoom cave here room = room & tunnels .~ t' + where t' = reachableFrom cave [Tunnel here 0] S.empty S.empty + +reachableFrom :: Cave -> [Tunnel] -> S.Set RoomID -> S.Set Tunnel -> S.Set Tunnel +reachableFrom _ [] _ routes = routes +reachableFrom cave (tunnel@(Tunnel here len):boundary) found routes + | here `S.member` found = reachableFrom cave boundary found routes + | otherwise = reachableFrom cave (boundary ++ (S.toList legs)) (S.insert here found) routes' + where exits = (cave ! here) ^. tunnels + exits' = S.filter (\t -> (t ^. tunnelTo) `S.notMember` found) exits + legs = S.map (\t -> t & tunnelLength .~ (len + 1)) exits' + routes' = if (len == 0) || ((cave ! here) ^. flowRate) == 0 + then routes + else S.insert tunnel routes + + +-- Parse the input file + +caveP :: Parser Cave +valveP :: Parser (RoomID, Room) +roomP :: Parser Room +tunnelsP :: Parser (S.Set Tunnel) +tunnelTextP :: Parser Text + +caveP = M.fromList <$> valveP `sepBy` endOfLine +valveP = (,) <$> ("Valve " *> (many1 letter)) <*> roomP +roomP = Room <$> (" has flow rate=" *> decimal) <*> (tunnelTextP *> tunnelsP) + -- where roomify v ts = Room {flowRate = v, tunnels = ts } +tunnelsP = (S.fromList . (fmap (flip Tunnel 1))) <$> (many1 letter) `sepBy` ", " +tunnelTextP = "; tunnels lead to valves " <|> "; tunnel leads to valve " + +successfulParse :: Text -> Cave +successfulParse input = + case parseOnly caveP input of + Left _err -> M.empty -- TIO.putStr $ T.pack $ parseErrorPretty err + Right cave -> cave \ No newline at end of file diff --git a/advent16/MainEstSort.hs b/advent16/MainEstSort.hs new file mode 100644 index 0000000..459a10b --- /dev/null +++ b/advent16/MainEstSort.hs @@ -0,0 +1,352 @@ +-- Writeup at https://work.njae.me.uk/2022/12/17/advent-of-code-2022-day-16/ + +-- import Debug.Trace + +import AoC +import Data.Text (Text) +import qualified Data.Text.IO as TIO +import Data.Attoparsec.Text hiding (take, D) +import Control.Applicative +import qualified Data.PQueue.Prio.Max as P +import qualified Data.Set as S +import qualified Data.Sequence as Q +import qualified Data.Map.Strict as M +import Data.Map.Strict ((!)) +-- import Data.Sequence ((|>), Seq((:|>)), ViewR ((:>))) +import Data.Sequence ( (|>), Seq((:|>)) ) +import Data.List +import Data.List.Split (chunksOf) +import Data.Ord +import Control.Monad.Reader +import Control.Lens hiding ((<|), (|>), (:>), (:<), indices) + + +type RoomID = String + +data Tunnel = Tunnel { _tunnelTo :: RoomID, _tunnelLength :: Int} + deriving (Eq, Show, Ord) +makeLenses ''Tunnel + +data Room = Room + { _flowRate :: Int + , _tunnels :: S.Set Tunnel + } deriving (Eq, Show, Ord) +makeLenses ''Room + +type Cave = M.Map RoomID Room +data TimedCave = TimedCave { getCave :: Cave, getTimeLimit :: Int } + +type CaveContext = Reader TimedCave + +data SingleSearchState = SingleSearchState + { _currentRoom :: RoomID + , _currentTime :: Int + , _sOpenValves :: S.Set RoomID + } deriving (Eq, Show, Ord) +makeLenses ''SingleSearchState + +data DoubleSearchState = DoubleSearchState + { _personRoom :: RoomID + , _personTime :: Int + , _elephantRoom :: RoomID + , _elephantTime :: Int + , _dOpenValves :: S.Set RoomID + } deriving (Eq, Show, Ord) +makeLenses ''DoubleSearchState + +data Agendum s = + Agendum { _current :: s + , _trail :: Q.Seq s + , _trailBenefit :: Int + , _benefit :: Int + } deriving (Show, Eq, Ord) +makeLenses ''Agendum + +type Agenda s = P.MaxPQueue Int (Agendum s) + +-- state, total flowed so far +type ExploredStates s = S.Set (s, Int) + + +class (Eq s, Ord s, Show s) => SearchState s where + emptySearchState :: RoomID -> s + currentFlow :: s -> CaveContext Int + timeOf :: s -> Int + successors :: s -> CaveContext (Q.Seq s) + -- estimateBenefit :: s -> Int -> CaveContext Int + estimateBenefit :: s -> CaveContext Int + +instance SearchState SingleSearchState where + emptySearchState startID = SingleSearchState + { _currentRoom = startID + , _currentTime = 0 + , _sOpenValves = S.empty + } + + currentFlow state = + do cave <- asks getCave + let valves = state ^. sOpenValves + let presentRooms = cave `M.restrictKeys` valves + return $ sumOf (folded . flowRate) presentRooms + + timeOf state = state ^. currentTime + + successors state = + do isFF <- isFullFlow state + -- cave <- asks getCave + timeLimit <- asks getTimeLimit + let here = state ^. currentRoom + let opened = state ^. sOpenValves + let now = state ^. currentTime + succs <- agentSuccessor now opened now here + let succStates = Q.fromList succs + if isFF || (Q.null succStates) + then return $ Q.singleton (state & currentTime .~ timeLimit) + else return succStates + + estimateBenefit here = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + let timeRemaining = timeLimit - (timeOf here) + cf <- currentFlow here + let closedValves = (cave `M.withoutKeys` (here ^. sOpenValves)) ^.. folded . flowRate + let sortedClosedValves = sortOn Down closedValves + let otherValveFlows = sum $ zipWith (*) [timeRemaining, (timeRemaining - 2) .. 0] sortedClosedValves + return $ (cf * timeRemaining) + otherValveFlows + + +instance SearchState DoubleSearchState where + emptySearchState startID = DoubleSearchState + { _personRoom = startID + , _personTime = 0 + , _elephantRoom = startID + , _elephantTime = 0 + , _dOpenValves = S.empty + } + + currentFlow state = + do cave <- asks getCave + let valves = S.toList $ state ^. dOpenValves + return $ sum $ fmap (\v -> (cave ! v) ^. flowRate) valves + -- let presentRooms = cave `M.restrictKeys` valves + -- return $ sumOf (folded . flowRate) presentRooms + + timeOf state = min (state ^. personTime) (state ^. elephantTime) + + successors state = + do isFF <- isFullFlow state + -- cave <- asks getCave + timeLimit <- asks getTimeLimit + let opened = state ^. dOpenValves + let pNow = state ^. personTime + let eNow = state ^. elephantTime + let now = min pNow eNow + let pHere = state ^. personRoom + let eHere = state ^. elephantRoom + pNexts <- agentSuccessor now opened pNow pHere + eNexts <- agentSuccessor now opened eNow eHere + let nexts = [ state & personRoom .~ (p ^. currentRoom) + & personTime .~ (p ^. currentTime) + & elephantRoom .~ (e ^. currentRoom) + & elephantTime .~ (e ^. currentTime) + & dOpenValves %~ (S.union (p ^. sOpenValves) . S.union (e ^. sOpenValves)) + | p <- pNexts + , e <- eNexts + ] + let dedups = if pNow == eNow && pHere == eHere + then filter (\s -> (s ^. personRoom) < (s ^. elephantRoom)) nexts + else nexts + -- let succStates = trace ("Succs: in " ++ (show state) ++ " out " ++ (show dedups)) (Q.fromList dedups) + let succStates = Q.fromList dedups + if isFF || (Q.null succStates) + then return $ Q.singleton (state & personTime .~ timeLimit & elephantTime .~ timeLimit) + else return succStates + + estimateBenefit here = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + let timeRemaining = timeLimit - (timeOf here) + cf <- currentFlow here + let closedValves = (cave `M.withoutKeys` (here ^. dOpenValves)) ^.. folded . flowRate + let sortedClosedValves = fmap sum $ chunksOf 2 $ {-# SCC estSort #-} sortOn Down closedValves + -- let sortedClosedValves = fmap sum $ chunksOf 2 $ reverse $ sort closedValves -- no significant improvement + let otherValveFlows = sum $ zipWith (*) [timeRemaining, (timeRemaining - 2) .. 0] sortedClosedValves + -- let otherValveFlows = timeRemaining * (sum closedValves) -- 8 minute runtime rather than 1:50 + return $ (cf * timeRemaining) + otherValveFlows + + +main :: IO () +main = + do dataFileName <- getDataFileName + text <- TIO.readFile dataFileName + let expandedCave = successfulParse text + -- print cave + -- print $ reachableFrom cave [Tunnel "AA" 0] S.empty [] + -- print $ compress cave + let cave = compress expandedCave + print $ part1 cave + print $ part2 cave + +-- part1 :: Cave -> Maybe (Agendum SingleSearchState) +-- part1 cave = runReader (searchCave "AA") (TimedCave cave 30) + +-- part2 :: Cave -> Maybe (Agendum DoubleSearchState) +-- part2 cave = runReader (searchCave "AA") (TimedCave cave 26) + +part1, part2 :: Cave -> Int +-- part1 :: Cave -> Int +part1 cave = maybe 0 _benefit result + where result = runReader (searchCave "AA") (TimedCave cave 30) :: Maybe (Agendum SingleSearchState) +part2 cave = maybe 0 _benefit result + where result = runReader (searchCave "AA") (TimedCave cave 26) :: Maybe (Agendum DoubleSearchState) + +searchCave :: SearchState s => String -> CaveContext (Maybe (Agendum s)) +searchCave startRoom = + do agenda <- initAgenda startRoom + aStar agenda S.empty + +initAgenda :: SearchState s => String -> CaveContext (Agenda s) +initAgenda startID = + do let startState = emptySearchState startID + b <- estimateBenefit startState + return $ P.singleton b Agendum { _current = startState, _trail = Q.empty, _trailBenefit = 0, _benefit = b} + +aStar :: SearchState s => Agenda s -> ExploredStates s -> CaveContext (Maybe (Agendum s)) +aStar agenda closed + -- | trace ("Peeping " ++ (show $ fst $ P.findMin agenda) ++ ": " ++ (show reached) ++ " <- " ++ (show $ toList $ Q.take 1 $ _trail $ currentAgendum) ++ " :: " ++ (show newAgenda)) False = undefined + -- | trace ("Peeping " ++ (show $ _current $ snd $ P.findMax agenda) ++ " : foundFlow " ++ (show $ _trailBenefit $ snd $ P.findMax agenda)) False = undefined + -- | trace ("Peeping " ++ (show $ P.findMax agenda)) False = undefined + | P.null agenda = return Nothing + | otherwise = + do let (_, currentAgendum) = P.findMax agenda + let reached = currentAgendum ^. current + nexts <- candidates currentAgendum closed + let newAgenda = foldl' (\q a -> P.insert (_benefit a) a q) (P.deleteMax agenda) nexts + -- let beamAgenda = P.fromDescList $ P.take 10000 newAgenda -- agenda beam width + -- let beamAgenda = P.fromDescList $ P.take 5000 newAgenda -- agenda beam width + -- let beamAgenda = P.fromDescList $ P.take 1000 newAgenda -- agenda beam width + reachedGoal <- isGoal currentAgendum + -- let cl = (reached, currentAgendum ^. trailBenefit, Q.length $ currentAgendum ^. trail) + let cl = (reached, currentAgendum ^. trailBenefit) + if reachedGoal + then return (Just currentAgendum) + else if (cl `S.member` closed) + then aStar (P.deleteMax agenda) closed + else aStar newAgenda (S.insert cl closed) + -- else aStar beamAgenda (S.insert cl closed) + + +candidates :: SearchState s => Agendum s -> ExploredStates s -> CaveContext (Q.Seq (Agendum s)) +candidates agendum closed = + do let candidate = agendum ^. current + let previous = agendum ^. trail + let prevBenefit = agendum ^. trailBenefit + succs <- successors candidate + succAgs <- mapM (makeAgendum previous prevBenefit) succs + -- let nonloops = Q.filter (\s -> (s ^. current, s ^. trailBenefit, Q.length $ s ^. trail) `S.notMember` closed) succAgs + let nonloops = Q.filter (\s -> (s ^. current, s ^. trailBenefit) `S.notMember` closed) succAgs + return nonloops + + +agentSuccessor :: Int -> S.Set RoomID -> Int -> RoomID -> CaveContext [SingleSearchState] +agentSuccessor now opened aTime here + | aTime /= now = return [SingleSearchState { _currentRoom = here, _currentTime = aTime, _sOpenValves = opened }] + | otherwise = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + let remaining = S.toList $ S.filter (\t -> (t ^. tunnelTo) `S.notMember` opened) ((cave ! here) ^. tunnels) + let moves = [ SingleSearchState + { _currentRoom = (t ^. tunnelTo) + , _currentTime = now + (t ^. tunnelLength) + , _sOpenValves = opened + } + | t <- remaining + , now + (t ^. tunnelLength) <= timeLimit + ] + let opens = if here `S.notMember` opened && (cave ! here) ^. flowRate > 0 + then [SingleSearchState { _currentRoom = here, _currentTime = aTime + 1, _sOpenValves = S.insert here opened }] + else [] + -- let nexts = moves ++ opens + let nexts = if null opens then moves else opens + let nexts' = if null nexts + then [ SingleSearchState + { _currentRoom = here + , _currentTime = timeLimit + , _sOpenValves = opened + } ] + else nexts + return nexts' + +makeAgendum :: SearchState s => Q.Seq s -> Int -> s -> CaveContext (Agendum s) +makeAgendum previous prevBenefit newState = + do predicted <- estimateBenefit newState -- (Q.length previous) + -- cf <- currentFlow newState + oldFlow <- lastFlow previous (timeOf newState) + let newTrail = previous |> newState + let incurred = prevBenefit + oldFlow + return Agendum { _current = newState + , _trail = newTrail + , _trailBenefit = incurred + , _benefit = incurred + predicted + } + +lastFlow :: SearchState s => Q.Seq s -> Int -> CaveContext Int +lastFlow Q.Empty _ = return 0 +lastFlow (_ :|> previous) newTime = + do cf <- currentFlow previous + let dt = newTime - (timeOf previous) + return (cf * dt) + +isGoal :: SearchState s => Agendum s -> CaveContext Bool +isGoal agendum = + do timeLimit <- asks getTimeLimit + let s = agendum ^. current + return $ (timeOf s) == timeLimit + +isFullFlow :: SearchState s => s -> CaveContext Bool +isFullFlow state = + do cave <- asks getCave + cf <- currentFlow state + let ff = sumOf (folded . flowRate) cave + return (cf == ff) + +compress :: Cave -> Cave +compress cave = M.mapWithKey (compressRoom cave) cave + +compressRoom :: Cave -> RoomID -> Room -> Room +compressRoom cave here room = room & tunnels .~ t' + where t' = reachableFrom cave [Tunnel here 0] S.empty S.empty + +reachableFrom :: Cave -> [Tunnel] -> S.Set RoomID -> S.Set Tunnel -> S.Set Tunnel +reachableFrom _ [] _ routes = routes +reachableFrom cave (tunnel@(Tunnel here len):boundary) found routes + | here `S.member` found = reachableFrom cave boundary found routes + | otherwise = reachableFrom cave (boundary ++ (S.toList legs)) (S.insert here found) routes' + where exits = (cave ! here) ^. tunnels + exits' = S.filter (\t -> (t ^. tunnelTo) `S.notMember` found) exits + legs = S.map (\t -> t & tunnelLength .~ (len + 1)) exits' + routes' = if (len == 0) || ((cave ! here) ^. flowRate) == 0 + then routes + else S.insert tunnel routes + + +-- Parse the input file + +caveP :: Parser Cave +valveP :: Parser (RoomID, Room) +roomP :: Parser Room +tunnelsP :: Parser (S.Set Tunnel) +tunnelTextP :: Parser Text + +caveP = M.fromList <$> valveP `sepBy` endOfLine +valveP = (,) <$> ("Valve " *> (many1 letter)) <*> roomP +roomP = Room <$> (" has flow rate=" *> decimal) <*> (tunnelTextP *> tunnelsP) + -- where roomify v ts = Room {flowRate = v, tunnels = ts } +tunnelsP = (S.fromList . (fmap (flip Tunnel 1))) <$> (many1 letter) `sepBy` ", " +tunnelTextP = "; tunnels lead to valves " <|> "; tunnel leads to valve " + +successfulParse :: Text -> Cave +successfulParse input = + case parseOnly caveP input of + Left _err -> M.empty -- TIO.putStr $ T.pack $ parseErrorPretty err + Right cave -> cave \ No newline at end of file diff --git a/advent16/MainOriginal.hs b/advent16/MainOriginal.hs new file mode 100644 index 0000000..3000671 --- /dev/null +++ b/advent16/MainOriginal.hs @@ -0,0 +1,275 @@ +-- Writeup at https://work.njae.me.uk/2022/12/17/advent-of-code-2022-day-16/ + +-- import Debug.Trace + +import AoC +import Data.Text (Text) +import qualified Data.Text.IO as TIO +import Data.Attoparsec.Text hiding (take, D) +import Control.Applicative +import qualified Data.PQueue.Prio.Max as P +import qualified Data.Set as S +import qualified Data.Sequence as Q +import qualified Data.Map.Strict as M +import Data.Map.Strict ((!)) +import Data.Sequence ((|>)) +import Data.List +import Data.List.Split (chunksOf) +import Data.Ord +import Control.Monad.Reader +import Control.Lens hiding ((<|), (|>), (:>), (:<), indices) + +-- pattern Empty <- (Q.viewl -> Q.EmptyL) where Empty = Q.empty +-- pattern x :< xs <- (Q.viewl -> x Q.:< xs) where (:<) = (Q.<|) +-- pattern xs :> x <- (Q.viewr -> xs Q.:> x) where (:>) = (Q.|>) + +type RoomID = String + +data Room = Room + { _flowRate :: Int + , _tunnels :: [RoomID] + } deriving (Eq, Show, Ord) +makeLenses ''Room + +type Cave = M.Map RoomID Room +data TimedCave = TimedCave { getCave :: Cave, getTimeLimit :: Int} + +type CaveContext = Reader TimedCave + +data SingleSearchState = SingleSearchState + { _currentRoom :: RoomID + , _sOpenValves :: S.Set RoomID + } deriving (Eq, Show, Ord) +makeLenses ''SingleSearchState + +data DoubleSearchState = DoubleSearchState + { _personRoom :: RoomID + , _elephantRoom :: RoomID + , _dOpenValves :: S.Set RoomID + } deriving (Eq, Show, Ord) +makeLenses ''DoubleSearchState + +data Agendum s = + Agendum { _current :: s + , _trail :: Q.Seq s + , _trailBenefit :: Int + , _benefit :: Int + } deriving (Show, Eq, Ord) +makeLenses ''Agendum + +type Agenda s = P.MaxPQueue Int (Agendum s) + +type ExploredStates s = S.Set (s, Int, Int) + + +class (Eq s, Ord s, Show s) => SearchState s where + emptySearchState :: RoomID -> s + currentFlow :: s -> CaveContext Int + successors :: s -> CaveContext (Q.Seq s) + estimateBenefit :: s -> Int -> CaveContext Int + +instance SearchState SingleSearchState where + emptySearchState startID = SingleSearchState { _currentRoom = startID, _sOpenValves = S.empty } + + currentFlow state = + do cave <- asks getCave + let valves = state ^. sOpenValves + let presentRooms = cave `M.restrictKeys` valves + return $ sumOf (folded . flowRate) presentRooms + + successors state = + do isFF <- isFullFlow state + let here = state ^. currentRoom + let opened = state ^. sOpenValves + succPairs <- personSuccessor here opened + let succStates = + [ SingleSearchState + { _currentRoom = r + , _sOpenValves = o + } + | (r, o) <- succPairs + ] + if isFF + then return $ Q.singleton state + else return $ Q.fromList succStates + + estimateBenefit here timeElapsed = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + let timeRemaining = timeLimit - (timeElapsed + 2) + cf <- currentFlow here + let closedValves = (cave `M.withoutKeys` (here ^. sOpenValves)) ^.. folded . flowRate + let sortedClosedValves = sortOn Down closedValves + let otherValveFlows = sum $ zipWith (*) [timeRemaining, (timeRemaining - 2) .. 0] sortedClosedValves + return $ (cf * timeRemaining) + otherValveFlows + + +instance SearchState DoubleSearchState where + emptySearchState startID = DoubleSearchState + { _personRoom = startID + , _elephantRoom = startID + , _dOpenValves = S.empty + } + + currentFlow state = + do cave <- asks getCave + let valves = state ^. dOpenValves + let presentRooms = cave `M.restrictKeys` valves + return $ sumOf (folded . flowRate) presentRooms + + successors state = + do isFF <- isFullFlow state + let pHere = state ^. personRoom + let eHere = state ^. elephantRoom + let opened = state ^. dOpenValves + pSuccPairs <- personSuccessor pHere opened + eSuccPairs <- personSuccessor eHere opened + let succStates = + [ DoubleSearchState + { _personRoom = p + , _elephantRoom = e + , _dOpenValves = S.union po eo + } + | (p, po) <- pSuccPairs + , (e, eo) <- eSuccPairs + ] + if isFF + then return $ Q.singleton state + else return $ Q.fromList succStates + + estimateBenefit here timeElapsed = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + let timeRemaining = timeLimit - (timeElapsed + 2) + cf <- currentFlow here + let closedValves = (cave `M.withoutKeys` (here ^. dOpenValves)) ^.. folded . flowRate + let sortedClosedValves = fmap sum $ chunksOf 2 $ sortOn Down closedValves + let otherValveFlows = sum $ zipWith (*) [timeRemaining, (timeRemaining - 2) .. 0] sortedClosedValves + return $ (cf * timeRemaining) + otherValveFlows + + +main :: IO () +main = + do dataFileName <- getDataFileName + text <- TIO.readFile dataFileName + let cave = successfulParse text + -- print cave + print $ part1 cave + print $ part2 cave + +-- part1 :: Cave -> Maybe (Agendum SingleSearchState) +-- part1 cave = runReader (searchCave "AA") (TimedCave cave 30) + +-- part2 :: Cave -> Maybe (Agendum DoubleSearchState) +-- part2 cave = runReader (searchCave "AA") (TimedCave cave 26) + +part1, part2 :: Cave -> Int +part1 cave = maybe 0 _benefit result + where result = runReader (searchCave "AA") (TimedCave cave 30) :: Maybe (Agendum SingleSearchState) +part2 cave = maybe 0 _benefit result + where result = runReader (searchCave "AA") (TimedCave cave 26) :: Maybe (Agendum DoubleSearchState) + +searchCave :: SearchState s => String -> CaveContext (Maybe (Agendum s)) +searchCave startRoom = + do agenda <- initAgenda startRoom + aStar agenda S.empty + +initAgenda :: SearchState s => String -> CaveContext (Agenda s) +initAgenda startID = + do let startState = emptySearchState startID + b <- estimateBenefit startState 0 + return $ P.singleton b Agendum { _current = startState, _trail = Q.empty, _trailBenefit = 0, _benefit = b} + +aStar :: SearchState s => Agenda s -> ExploredStates s -> CaveContext (Maybe (Agendum s)) +aStar agenda closed + -- | trace ("Peeping " ++ (show $ fst $ P.findMin agenda) ++ ": " ++ (show reached) ++ " <- " ++ (show $ toList $ Q.take 1 $ _trail $ currentAgendum) ++ " :: " ++ (show newAgenda)) False = undefined + -- | trace ("Peeping " ++ (show $ _current $ snd $ P.findMax agenda) ++ " : len " ++ (show $ Q.length $ _trail $ snd $ P.findMax agenda)) False = undefined + | P.null agenda = return Nothing + | otherwise = + do let (_, currentAgendum) = P.findMax agenda + let reached = currentAgendum ^. current + nexts <- candidates currentAgendum closed + let newAgenda = foldl' (\q a -> P.insert (_benefit a) a q) (P.deleteMax agenda) nexts + -- let beamAgenda = P.fromDescList $ P.take 10000 newAgenda -- agenda beam width + let beamAgenda = P.fromDescList $ P.take 5000 newAgenda -- agenda beam width + reachedGoal <- isGoal currentAgendum + let cl = (reached, currentAgendum ^. trailBenefit, Q.length $ currentAgendum ^. trail) + if reachedGoal + then return (Just currentAgendum) + else if (cl `S.member` closed) + then aStar (P.deleteMax agenda) closed + -- else aStar newAgenda (S.insert cl closed) + else aStar beamAgenda (S.insert cl closed) + + +candidates :: SearchState s => Agendum s -> ExploredStates s -> CaveContext (Q.Seq (Agendum s)) +candidates agendum closed = + do let candidate = agendum ^. current + let previous = agendum ^. trail + let prevBenefit = agendum ^. trailBenefit + succs <- successors candidate + succAgs <- mapM (makeAgendum previous prevBenefit) succs + let nonloops = Q.filter (\s -> (s ^. current, s ^. trailBenefit, Q.length $ s ^. trail) `S.notMember` closed) succAgs + return nonloops + +personSuccessor, openValveSuccessor, walkSuccessor :: RoomID -> S.Set RoomID -> CaveContext [(RoomID, S.Set RoomID)] +personSuccessor here opened = + do ovs <- openValveSuccessor here opened + ws <- walkSuccessor here opened + return (ovs ++ ws) + +openValveSuccessor here opened + | here `S.member` opened = return [] + | otherwise = return [(here, S.insert here opened)] + +walkSuccessor here opened = + do cave <- asks getCave + let neighbours = (cave ! here) ^. tunnels + return [(n, opened) | n <- neighbours] + +makeAgendum :: SearchState s => Q.Seq s -> Int -> s -> CaveContext (Agendum s) +makeAgendum previous prevBenefit newState = + do predicted <- estimateBenefit newState (Q.length previous) + cf <- currentFlow newState + let newTrail = previous |> newState + let incurred = prevBenefit + cf + return Agendum { _current = newState + , _trail = newTrail + , _trailBenefit = incurred + , _benefit = incurred + predicted + } + + +isGoal :: SearchState s => Agendum s -> CaveContext Bool +isGoal agendum = + do timeLimit <- asks getTimeLimit + return $ Q.length (agendum ^. trail) == (timeLimit - 1) + +isFullFlow :: SearchState s => s -> CaveContext Bool +isFullFlow state = + do cave <- asks getCave + cf <- currentFlow state + let ff = sumOf (folded . flowRate) cave + return (cf == ff) + + +-- Parse the input file + +caveP :: Parser Cave +valveP :: Parser (RoomID, Room) +roomP :: Parser Room +tunnelsP :: Parser [RoomID] +tunnelTextP :: Parser Text + +caveP = M.fromList <$> valveP `sepBy` endOfLine +valveP = (,) <$> ("Valve " *> (many1 letter)) <*> roomP +roomP = roomify <$> (" has flow rate=" *> decimal) <*> (tunnelTextP *> tunnelsP) + where roomify v ts = Room {_flowRate = v, _tunnels = ts } +tunnelsP = (many1 letter) `sepBy` ", " +tunnelTextP = "; tunnels lead to valves " <|> "; tunnel leads to valve " + +successfulParse :: Text -> Cave +successfulParse input = + case parseOnly caveP input of + Left _err -> M.empty -- TIO.putStr $ T.pack $ parseErrorPretty err + Right cave -> cave \ No newline at end of file diff --git a/advent16/MainOriginalNoBeam.hs b/advent16/MainOriginalNoBeam.hs new file mode 100644 index 0000000..b074d93 --- /dev/null +++ b/advent16/MainOriginalNoBeam.hs @@ -0,0 +1,275 @@ +-- Writeup at https://work.njae.me.uk/2022/12/17/advent-of-code-2022-day-16/ + +-- import Debug.Trace + +import AoC +import Data.Text (Text) +import qualified Data.Text.IO as TIO +import Data.Attoparsec.Text hiding (take, D) +import Control.Applicative +import qualified Data.PQueue.Prio.Max as P +import qualified Data.Set as S +import qualified Data.Sequence as Q +import qualified Data.Map.Strict as M +import Data.Map.Strict ((!)) +import Data.Sequence ((|>)) +import Data.List +import Data.List.Split (chunksOf) +import Data.Ord +import Control.Monad.Reader +import Control.Lens hiding ((<|), (|>), (:>), (:<), indices) + +-- pattern Empty <- (Q.viewl -> Q.EmptyL) where Empty = Q.empty +-- pattern x :< xs <- (Q.viewl -> x Q.:< xs) where (:<) = (Q.<|) +-- pattern xs :> x <- (Q.viewr -> xs Q.:> x) where (:>) = (Q.|>) + +type RoomID = String + +data Room = Room + { _flowRate :: Int + , _tunnels :: [RoomID] + } deriving (Eq, Show, Ord) +makeLenses ''Room + +type Cave = M.Map RoomID Room +data TimedCave = TimedCave { getCave :: Cave, getTimeLimit :: Int} + +type CaveContext = Reader TimedCave + +data SingleSearchState = SingleSearchState + { _currentRoom :: RoomID + , _sOpenValves :: S.Set RoomID + } deriving (Eq, Show, Ord) +makeLenses ''SingleSearchState + +data DoubleSearchState = DoubleSearchState + { _personRoom :: RoomID + , _elephantRoom :: RoomID + , _dOpenValves :: S.Set RoomID + } deriving (Eq, Show, Ord) +makeLenses ''DoubleSearchState + +data Agendum s = + Agendum { _current :: s + , _trail :: Q.Seq s + , _trailBenefit :: Int + , _benefit :: Int + } deriving (Show, Eq, Ord) +makeLenses ''Agendum + +type Agenda s = P.MaxPQueue Int (Agendum s) + +type ExploredStates s = S.Set (s, Int, Int) + + +class (Eq s, Ord s, Show s) => SearchState s where + emptySearchState :: RoomID -> s + currentFlow :: s -> CaveContext Int + successors :: s -> CaveContext (Q.Seq s) + estimateBenefit :: s -> Int -> CaveContext Int + +instance SearchState SingleSearchState where + emptySearchState startID = SingleSearchState { _currentRoom = startID, _sOpenValves = S.empty } + + currentFlow state = + do cave <- asks getCave + let valves = state ^. sOpenValves + let presentRooms = cave `M.restrictKeys` valves + return $ sumOf (folded . flowRate) presentRooms + + successors state = + do isFF <- isFullFlow state + let here = state ^. currentRoom + let opened = state ^. sOpenValves + succPairs <- personSuccessor here opened + let succStates = + [ SingleSearchState + { _currentRoom = r + , _sOpenValves = o + } + | (r, o) <- succPairs + ] + if isFF + then return $ Q.singleton state + else return $ Q.fromList succStates + + estimateBenefit here timeElapsed = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + let timeRemaining = timeLimit - (timeElapsed + 2) + cf <- currentFlow here + let closedValves = (cave `M.withoutKeys` (here ^. sOpenValves)) ^.. folded . flowRate + let sortedClosedValves = sortOn Down closedValves + let otherValveFlows = sum $ zipWith (*) [timeRemaining, (timeRemaining - 2) .. 0] sortedClosedValves + return $ (cf * timeRemaining) + otherValveFlows + + +instance SearchState DoubleSearchState where + emptySearchState startID = DoubleSearchState + { _personRoom = startID + , _elephantRoom = startID + , _dOpenValves = S.empty + } + + currentFlow state = + do cave <- asks getCave + let valves = state ^. dOpenValves + let presentRooms = cave `M.restrictKeys` valves + return $ sumOf (folded . flowRate) presentRooms + + successors state = + do isFF <- isFullFlow state + let pHere = state ^. personRoom + let eHere = state ^. elephantRoom + let opened = state ^. dOpenValves + pSuccPairs <- personSuccessor pHere opened + eSuccPairs <- personSuccessor eHere opened + let succStates = + [ DoubleSearchState + { _personRoom = p + , _elephantRoom = e + , _dOpenValves = S.union po eo + } + | (p, po) <- pSuccPairs + , (e, eo) <- eSuccPairs + ] + if isFF + then return $ Q.singleton state + else return $ Q.fromList succStates + + estimateBenefit here timeElapsed = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + let timeRemaining = timeLimit - (timeElapsed + 2) + cf <- currentFlow here + let closedValves = (cave `M.withoutKeys` (here ^. dOpenValves)) ^.. folded . flowRate + let sortedClosedValves = fmap sum $ chunksOf 2 $ sortOn Down closedValves + let otherValveFlows = sum $ zipWith (*) [timeRemaining, (timeRemaining - 2) .. 0] sortedClosedValves + return $ (cf * timeRemaining) + otherValveFlows + + +main :: IO () +main = + do dataFileName <- getDataFileName + text <- TIO.readFile dataFileName + let cave = successfulParse text + -- print cave + print $ part1 cave + print $ part2 cave + +-- part1 :: Cave -> Maybe (Agendum SingleSearchState) +-- part1 cave = runReader (searchCave "AA") (TimedCave cave 30) + +-- part2 :: Cave -> Maybe (Agendum DoubleSearchState) +-- part2 cave = runReader (searchCave "AA") (TimedCave cave 26) + +part1, part2 :: Cave -> Int +part1 cave = maybe 0 _benefit result + where result = runReader (searchCave "AA") (TimedCave cave 30) :: Maybe (Agendum SingleSearchState) +part2 cave = maybe 0 _benefit result + where result = runReader (searchCave "AA") (TimedCave cave 26) :: Maybe (Agendum DoubleSearchState) + +searchCave :: SearchState s => String -> CaveContext (Maybe (Agendum s)) +searchCave startRoom = + do agenda <- initAgenda startRoom + aStar agenda S.empty + +initAgenda :: SearchState s => String -> CaveContext (Agenda s) +initAgenda startID = + do let startState = emptySearchState startID + b <- estimateBenefit startState 0 + return $ P.singleton b Agendum { _current = startState, _trail = Q.empty, _trailBenefit = 0, _benefit = b} + +aStar :: SearchState s => Agenda s -> ExploredStates s -> CaveContext (Maybe (Agendum s)) +aStar agenda closed + -- | trace ("Peeping " ++ (show $ fst $ P.findMin agenda) ++ ": " ++ (show reached) ++ " <- " ++ (show $ toList $ Q.take 1 $ _trail $ currentAgendum) ++ " :: " ++ (show newAgenda)) False = undefined + -- | trace ("Peeping " ++ (show $ _current $ snd $ P.findMax agenda) ++ " : len " ++ (show $ Q.length $ _trail $ snd $ P.findMax agenda)) False = undefined + | P.null agenda = return Nothing + | otherwise = + do let (_, currentAgendum) = P.findMax agenda + let reached = currentAgendum ^. current + nexts <- candidates currentAgendum closed + let newAgenda = foldl' (\q a -> P.insert (_benefit a) a q) (P.deleteMax agenda) nexts + -- let beamAgenda = P.fromDescList $ P.take 10000 newAgenda -- agenda beam width + -- let beamAgenda = P.fromDescList $ P.take 5000 newAgenda -- agenda beam width + reachedGoal <- isGoal currentAgendum + let cl = (reached, currentAgendum ^. trailBenefit, Q.length $ currentAgendum ^. trail) + if reachedGoal + then return (Just currentAgendum) + else if (cl `S.member` closed) + then aStar (P.deleteMax agenda) closed + else aStar newAgenda (S.insert cl closed) + -- else aStar beamAgenda (S.insert cl closed) + + +candidates :: SearchState s => Agendum s -> ExploredStates s -> CaveContext (Q.Seq (Agendum s)) +candidates agendum closed = + do let candidate = agendum ^. current + let previous = agendum ^. trail + let prevBenefit = agendum ^. trailBenefit + succs <- successors candidate + succAgs <- mapM (makeAgendum previous prevBenefit) succs + let nonloops = Q.filter (\s -> (s ^. current, s ^. trailBenefit, Q.length $ s ^. trail) `S.notMember` closed) succAgs + return nonloops + +personSuccessor, openValveSuccessor, walkSuccessor :: RoomID -> S.Set RoomID -> CaveContext [(RoomID, S.Set RoomID)] +personSuccessor here opened = + do ovs <- openValveSuccessor here opened + ws <- walkSuccessor here opened + return (ovs ++ ws) + +openValveSuccessor here opened + | here `S.member` opened = return [] + | otherwise = return [(here, S.insert here opened)] + +walkSuccessor here opened = + do cave <- asks getCave + let neighbours = (cave ! here) ^. tunnels + return [(n, opened) | n <- neighbours] + +makeAgendum :: SearchState s => Q.Seq s -> Int -> s -> CaveContext (Agendum s) +makeAgendum previous prevBenefit newState = + do predicted <- estimateBenefit newState (Q.length previous) + cf <- currentFlow newState + let newTrail = previous |> newState + let incurred = prevBenefit + cf + return Agendum { _current = newState + , _trail = newTrail + , _trailBenefit = incurred + , _benefit = incurred + predicted + } + + +isGoal :: SearchState s => Agendum s -> CaveContext Bool +isGoal agendum = + do timeLimit <- asks getTimeLimit + return $ Q.length (agendum ^. trail) == (timeLimit - 1) + +isFullFlow :: SearchState s => s -> CaveContext Bool +isFullFlow state = + do cave <- asks getCave + cf <- currentFlow state + let ff = sumOf (folded . flowRate) cave + return (cf == ff) + + +-- Parse the input file + +caveP :: Parser Cave +valveP :: Parser (RoomID, Room) +roomP :: Parser Room +tunnelsP :: Parser [RoomID] +tunnelTextP :: Parser Text + +caveP = M.fromList <$> valveP `sepBy` endOfLine +valveP = (,) <$> ("Valve " *> (many1 letter)) <*> roomP +roomP = roomify <$> (" has flow rate=" *> decimal) <*> (tunnelTextP *> tunnelsP) + where roomify v ts = Room {_flowRate = v, _tunnels = ts } +tunnelsP = (many1 letter) `sepBy` ", " +tunnelTextP = "; tunnels lead to valves " <|> "; tunnel leads to valve " + +successfulParse :: Text -> Cave +successfulParse input = + case parseOnly caveP input of + Left _err -> M.empty -- TIO.putStr $ T.pack $ parseErrorPretty err + Right cave -> cave \ No newline at end of file diff --git a/advent16/MainSPar.hs b/advent16/MainSPar.hs new file mode 100644 index 0000000..d3be5ec --- /dev/null +++ b/advent16/MainSPar.hs @@ -0,0 +1,323 @@ +-- Writeup at https://work.njae.me.uk/2022/12/17/advent-of-code-2022-day-16/ + +import Debug.Trace + +import AoC +import Data.Text (Text) +import qualified Data.Text.IO as TIO +import Data.Attoparsec.Text hiding (take, D) +import Control.Applicative +import qualified Data.PQueue.Prio.Max as P +import qualified Data.Set as S +import qualified Data.Sequence as Q +import qualified Data.Map.Strict as M +import Data.Map.Strict ((!)) +-- import Data.Sequence ((|>), Seq((:|>)), ViewR ((:>))) +import Data.Sequence ( (|>), Seq((:|>)) ) +import Data.List +import Data.List.Split (chunksOf) +import Data.Ord +import Control.Monad.Reader +import Control.Lens hiding ((<|), (|>), (:>), (:<), indices) +import Control.Parallel.Strategies + + +type RoomID = String + +data Tunnel = Tunnel { _tunnelTo :: RoomID, _tunnelLength :: Int} + deriving (Eq, Show, Ord) +makeLenses ''Tunnel + +data Room = Room + { _flowRate :: Int + , _tunnels :: S.Set Tunnel + } deriving (Eq, Show, Ord) +makeLenses ''Room + +type Cave = M.Map RoomID Room +data TimedCave = TimedCave { getCave :: Cave, getTimeLimit :: Int , getSortedRooms :: [RoomID]} + +type CaveContext = Reader TimedCave + +data SearchState = SearchState + { _currentRoom :: RoomID + , _currentTime :: Int + , _openValves :: S.Set RoomID + } deriving (Eq, Show, Ord) +makeLenses ''SearchState + +data Agendum = + Agendum { _current :: SearchState + , _trail :: Q.Seq SearchState + , _trailBenefit :: Int + , _benefit :: Int + } deriving (Show, Eq, Ord) +makeLenses ''Agendum + +type Agenda = P.MaxPQueue Int Agendum + +-- state, total flowed so far +type ExploredStates = S.Set (SearchState, Int) + +type PartSolutions = M.Map (S.Set RoomID) Int + + +main :: IO () +main = + do dataFileName <- getDataFileName + text <- TIO.readFile dataFileName + let expandedCave = successfulParse text + -- print cave + -- print $ reachableFrom cave [Tunnel "AA" 0] S.empty [] + -- print $ compress cave + -- putStrLn $ dotify expandedCave + let cave = compress expandedCave + print $ part1 cave + print $ part2 cave + +-- dotify cave = "graph G {\n" ++ (unlines $ concat $ M.elems $ M.mapWithKey showCRoom cave) ++ "\n}\n" +-- where showCRoom roomID room = filter (not . null) ((showCRoomShape roomID room) : (showCRoomLinks roomID room)) + +-- showCRoomShape roomID room +-- | room ^. flowRate > 0 = roomID ++ " [fillcolor=grey label=\"" ++ roomID ++ ": " ++ (show $ room ^. flowRate) ++ "\"];" +-- | otherwise = "" + +-- showCRoomLinks roomID room = [roomID ++ " -- " ++ (t ^. tunnelTo) ++ ";" | t <- S.toList $ room ^. tunnels, (t ^. tunnelTo) > roomID ] + +part1, part2 :: Cave -> Int +-- part1 :: Cave -> Int +part1 cave = runSearch 30 cave +part2 cave = maximum (fmap maximum chunkSolns `using` parList rdeepseq) + where rawSolutions = runSearchAll 26 cave + solutionList = M.toList rawSolutions + combinations = [ fp + fe + | (p, fp) <- solutionList + , (e, fe) <- solutionList + , p < e + , S.disjoint p e + ] + chunkSolns = chunksOf 10000 combinations + +includeAgendum :: PartSolutions -> Agendum -> CaveContext PartSolutions +includeAgendum results agendum = + do cf <- currentFlow (agendum ^. current) + timeLimit <- asks getTimeLimit + let timeLeft = timeLimit - timeOf (agendum ^. current) + let remainingFlow = cf * timeLeft + let totalFlow = remainingFlow + agendum ^. trailBenefit + let visitedSet = agendum ^. current . openValves + let currentBest = M.findWithDefault 0 visitedSet results + if totalFlow > currentBest + then return (M.insert visitedSet totalFlow results) + else return results + +runSearch :: Int -> Cave -> Int +runSearch timeLimit cave = maybe 0 _benefit result + where result = runReader (searchCave "AA") (TimedCave cave timeLimit sortedRooms) + sortedRooms = sortOn (\r -> Down $ (cave ! r) ^. flowRate ) $ M.keys $ M.filter (\r -> r ^. flowRate > 0) cave + +runSearchAll :: Int -> Cave -> PartSolutions +runSearchAll timeLimit cave = result + where result = runReader (searchCaveAll "AA") (TimedCave cave timeLimit sortedRooms) + sortedRooms = sortOn (\r -> Down $ (cave ! r) ^. flowRate ) $ M.keys $ M.filter (\r -> r ^. flowRate > 0) cave + + +searchCave :: String -> CaveContext (Maybe Agendum) +searchCave startRoom = + do agenda <- initAgenda startRoom + aStar agenda S.empty + +searchCaveAll :: String -> CaveContext PartSolutions +searchCaveAll startRoom = + do agenda <- initAgenda startRoom + allSolutions agenda S.empty M.empty + +initAgenda :: String -> CaveContext Agenda +initAgenda startID = + do let startState = emptySearchState startID + b <- estimateBenefit startState + return $ P.singleton b Agendum { _current = startState, _trail = Q.empty, _trailBenefit = 0, _benefit = b} + +aStar :: Agenda -> ExploredStates -> CaveContext (Maybe Agendum) +aStar agenda closed + -- | trace ("Peeping " ++ (show $ fst $ P.findMin agenda) ++ ": " ++ (show reached) ++ " <- " ++ (show $ toList $ Q.take 1 $ _trail $ currentAgendum) ++ " :: " ++ (show newAgenda)) False = undefined + -- | trace ("Peeping " ++ (show $ _current $ snd $ P.findMax agenda) ++ " : foundFlow " ++ (show $ _trailBenefit $ snd $ P.findMax agenda)) False = undefined + -- | trace ("Peeping " ++ (show $ _current $ snd $ P.findMax agenda) ++ " : foundFlow " ++ (show $ _trailBenefit $ snd $ P.findMax agenda) ++ " : trail " ++ (show $ _trail $ snd $ P.findMax agenda) ++ " : closed " ++ (show closed)) False = undefined + -- | trace ("Peeping " ++ (show $ P.findMax agenda)) False = undefined + | P.null agenda = return Nothing + | otherwise = + do let (_, currentAgendum) = P.findMax agenda + let reached = currentAgendum ^. current + nexts <- candidates currentAgendum closed + let newAgenda = foldl' (\q a -> P.insert (_benefit a) a q) (P.deleteMax agenda) nexts + reachedGoal <- isGoal currentAgendum + let cl = (reached, currentAgendum ^. trailBenefit) + if reachedGoal + then return (Just currentAgendum) + else if (cl `S.member` closed) + then aStar (P.deleteMax agenda) closed + else aStar newAgenda (S.insert cl closed) + +allSolutions :: Agenda -> ExploredStates -> PartSolutions -> CaveContext PartSolutions +allSolutions agenda closed foundSolutions + | P.null agenda = return foundSolutions + | otherwise = + do let (_, currentAgendum) = P.findMax agenda + let reached = currentAgendum ^. current + nexts <- candidates currentAgendum closed + let newAgenda = foldl' (\q a -> P.insert (_benefit a) a q) (P.deleteMax agenda) nexts + reachedGoal <- isGoal currentAgendum + let cl = (reached, currentAgendum ^. trailBenefit) + newFoundSolutions <- includeAgendum foundSolutions currentAgendum + if reachedGoal + then allSolutions (P.deleteMax agenda) closed newFoundSolutions + else if (cl `S.member` closed) + then allSolutions (P.deleteMax agenda) closed foundSolutions + else allSolutions newAgenda (S.insert cl closed) newFoundSolutions + + +candidates :: Agendum -> ExploredStates -> CaveContext (Q.Seq Agendum) +candidates agendum closed = + do let candidate = agendum ^. current + let previous = agendum ^. trail + let prevBenefit = agendum ^. trailBenefit + succs <- successors candidate + succAgs <- mapM (makeAgendum previous prevBenefit) succs + let nonloops = Q.filter (\s -> (s ^. current, s ^. trailBenefit) `S.notMember` closed) succAgs + return nonloops + +emptySearchState :: RoomID -> SearchState +emptySearchState startID = SearchState + { _currentRoom = startID + , _currentTime = 0 + , _openValves = S.empty + } + +currentFlow :: SearchState -> CaveContext Int +currentFlow state = + do cave <- asks getCave + let valves = state ^. openValves + let presentRooms = cave `M.restrictKeys` valves + return $ sumOf (folded . flowRate) presentRooms + +timeOf :: SearchState -> Int +timeOf state = state ^. currentTime + +successors :: SearchState -> CaveContext (Q.Seq SearchState) +successors state = + do isFF <- isFullFlow state + cave <- asks getCave + timeLimit <- asks getTimeLimit + let here = state ^. currentRoom + let opened = state ^. openValves + let now = state ^. currentTime + let remaining = S.toList $ S.filter (\t -> (t ^. tunnelTo) `S.notMember` opened) ((cave ! here) ^. tunnels) + let moves = [ SearchState + { _currentRoom = (t ^. tunnelTo) + , _currentTime = now + (t ^. tunnelLength) + , _openValves = opened + } + | t <- remaining + , now + (t ^. tunnelLength) <= timeLimit + ] + let opens = if here `S.notMember` opened && (cave ! here) ^. flowRate > 0 && now < timeLimit + then [SearchState { _currentRoom = here, _currentTime = now + 1, _openValves = S.insert here opened }] + else [] + let nexts = if null opens then moves else opens + let nexts' = if null nexts + then [ SearchState + { _currentRoom = here + , _currentTime = timeLimit + , _openValves = opened + } ] + else nexts + let succs = Q.fromList nexts' + if isFF || (Q.null succs) + then return $ Q.singleton (state & currentTime .~ timeLimit) + else return succs + + +estimateBenefit :: SearchState -> CaveContext Int +estimateBenefit here = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + let timeRemaining = timeLimit - (timeOf here) + cf <- currentFlow here + sortedValves <- asks getSortedRooms + let opened = here ^. openValves + let sortedClosedValves = [(cave ! v) ^. flowRate | v <- sortedValves, v `S.notMember` opened] + let otherValveFlows = sum $ zipWith (*) [timeRemaining, (timeRemaining - 2) .. 0] sortedClosedValves + return $ (cf * timeRemaining) + otherValveFlows + +makeAgendum :: Q.Seq SearchState -> Int -> SearchState -> CaveContext Agendum +makeAgendum previous prevBenefit newState = + do predicted <- estimateBenefit newState -- (Q.length previous) + -- cf <- currentFlow newState + oldFlow <- lastFlow previous (timeOf newState) + let newTrail = previous |> newState + let incurred = prevBenefit + oldFlow + return Agendum { _current = newState + , _trail = newTrail + , _trailBenefit = incurred + , _benefit = incurred + predicted + } + +lastFlow :: Q.Seq SearchState -> Int -> CaveContext Int +lastFlow Q.Empty _ = return 0 +lastFlow (_ :|> previous) newTime = + do cf <- currentFlow previous + let dt = newTime - (timeOf previous) + return (cf * dt) + +isGoal :: Agendum -> CaveContext Bool +isGoal agendum = + do timeLimit <- asks getTimeLimit + let s = agendum ^. current + return $ (timeOf s) == timeLimit + +isFullFlow :: SearchState -> CaveContext Bool +isFullFlow state = + do cave <- asks getCave + cf <- currentFlow state + let ff = sumOf (folded . flowRate) cave + return (cf == ff) + +compress :: Cave -> Cave +compress cave = M.mapWithKey (compressRoom cave) cave + +compressRoom :: Cave -> RoomID -> Room -> Room +compressRoom cave here room = room & tunnels .~ t' + where t' = reachableFrom cave [Tunnel here 0] S.empty S.empty + +reachableFrom :: Cave -> [Tunnel] -> S.Set RoomID -> S.Set Tunnel -> S.Set Tunnel +reachableFrom _ [] _ routes = routes +reachableFrom cave (tunnel@(Tunnel here len):boundary) found routes + | here `S.member` found = reachableFrom cave boundary found routes + | otherwise = reachableFrom cave (boundary ++ (S.toList legs)) (S.insert here found) routes' + where exits = (cave ! here) ^. tunnels + exits' = S.filter (\t -> (t ^. tunnelTo) `S.notMember` found) exits + legs = S.map (\t -> t & tunnelLength .~ (len + 1)) exits' + routes' = if (len == 0) || ((cave ! here) ^. flowRate) == 0 + then routes + else S.insert tunnel routes + +-- Parse the input file + +caveP :: Parser Cave +valveP :: Parser (RoomID, Room) +roomP :: Parser Room +tunnelsP :: Parser (S.Set Tunnel) +tunnelTextP :: Parser Text + +caveP = M.fromList <$> valveP `sepBy` endOfLine +valveP = (,) <$> ("Valve " *> (many1 letter)) <*> roomP +roomP = Room <$> (" has flow rate=" *> decimal) <*> (tunnelTextP *> tunnelsP) + -- where roomify v ts = Room {flowRate = v, tunnels = ts } +tunnelsP = (S.fromList . (fmap (flip Tunnel 1))) <$> (many1 letter) `sepBy` ", " +tunnelTextP = "; tunnels lead to valves " <|> "; tunnel leads to valve " + +successfulParse :: Text -> Cave +successfulParse input = + case parseOnly caveP input of + Left _err -> M.empty -- TIO.putStr $ T.pack $ parseErrorPretty err + Right cave -> cave \ No newline at end of file diff --git a/advent16/MainSubsets.hs b/advent16/MainSubsets.hs new file mode 100644 index 0000000..b927188 --- /dev/null +++ b/advent16/MainSubsets.hs @@ -0,0 +1,309 @@ +-- Writeup at https://work.njae.me.uk/2022/12/17/advent-of-code-2022-day-16/ + +import Debug.Trace + +import AoC +import Data.Text (Text) +import qualified Data.Text.IO as TIO +import Data.Attoparsec.Text hiding (take, D) +import Control.Applicative +import qualified Data.PQueue.Prio.Max as P +import qualified Data.Set as S +import qualified Data.Sequence as Q +import qualified Data.Map.Strict as M +import Data.Map.Strict ((!)) +-- import Data.Sequence ((|>), Seq((:|>)), ViewR ((:>))) +import Data.Sequence ( (|>), Seq((:|>)) ) +import Data.List +-- import Data.List.Split (chunksOf) +import Data.Ord +import Control.Monad.Reader +import Control.Lens hiding ((<|), (|>), (:>), (:<), indices) + +type RoomID = String + +data Tunnel = Tunnel { _tunnelTo :: RoomID, _tunnelLength :: Int} + deriving (Eq, Show, Ord) +makeLenses ''Tunnel + +data Room = Room + { _flowRate :: Int + , _tunnels :: S.Set Tunnel + } deriving (Eq, Show, Ord) +makeLenses ''Room + +type Cave = M.Map RoomID Room +data TimedCave = TimedCave { getCave :: Cave, getTimeLimit :: Int , getSortedRooms :: [RoomID]} + +type CaveContext = Reader TimedCave + +data SearchState = SearchState + { _currentRoom :: RoomID + , _currentTime :: Int + , _openValves :: S.Set RoomID + } deriving (Eq, Show, Ord) +makeLenses ''SearchState + +data Agendum = + Agendum { _current :: SearchState + , _trail :: Q.Seq SearchState + , _trailBenefit :: Int + , _benefit :: Int + } deriving (Show, Eq, Ord) +makeLenses ''Agendum + +type Agenda = P.MaxPQueue Int Agendum + +-- state, total flowed so far +type ExploredStates = S.Set (SearchState, Int) + +type PartSolutions = M.Map (S.Set RoomID) Int + + +main :: IO () +main = + do dataFileName <- getDataFileName + text <- TIO.readFile dataFileName + let expandedCave = successfulParse text + -- print cave + -- print $ reachableFrom cave [Tunnel "AA" 0] S.empty [] + -- print $ compress cave + let cave = compress expandedCave + print $ part1 cave + print $ part2 cave + +part1, part2 :: Cave -> Int +-- part1 :: Cave -> Int +part1 cave = runSearch 30 cave +part2 cave = maximum combinations + where rawSolutions = runSearchAll 26 cave + solutionList = M.toList rawSolutions + combinations = [ (f1 + f2) + | (p, f1) <- solutionList + , (e, f2) <- solutionList + , p < e + , S.disjoint p e + ] + +includeAgendum :: PartSolutions -> Agendum -> CaveContext PartSolutions +includeAgendum results agendum = + do cf <- currentFlow (agendum ^. current) + timeLimit <- asks getTimeLimit + let timeLeft = timeLimit - timeOf (agendum ^. current) + let remainingFlow = cf * timeLeft + let totalFlow = remainingFlow + agendum ^. trailBenefit + let visitedSet = agendum ^. current . openValves + let currentBest = M.findWithDefault 0 visitedSet results + if totalFlow > currentBest + then return (M.insert visitedSet totalFlow results) + else return results + +runSearch :: Int -> Cave -> Int +runSearch timeLimit cave = maybe 0 _benefit result + where result = runReader (searchCave "AA") (TimedCave cave timeLimit sortedRooms) + sortedRooms = sortOn (\r -> Down $ (cave ! r) ^. flowRate ) $ M.keys $ M.filter (\r -> r ^. flowRate > 0) cave + +runSearchAll :: Int -> Cave -> PartSolutions +runSearchAll timeLimit cave = result + where result = runReader (searchCaveAll "AA") (TimedCave cave timeLimit sortedRooms) + sortedRooms = sortOn (\r -> Down $ (cave ! r) ^. flowRate ) $ M.keys $ M.filter (\r -> r ^. flowRate > 0) cave + + +searchCave :: String -> CaveContext (Maybe Agendum) +searchCave startRoom = + do agenda <- initAgenda startRoom + aStar agenda S.empty + +searchCaveAll :: String -> CaveContext PartSolutions +searchCaveAll startRoom = + do agenda <- initAgenda startRoom + allSolutions agenda S.empty M.empty + +initAgenda :: String -> CaveContext Agenda +initAgenda startID = + do let startState = emptySearchState startID + b <- estimateBenefit startState + return $ P.singleton b Agendum { _current = startState, _trail = Q.empty, _trailBenefit = 0, _benefit = b} + +aStar :: Agenda -> ExploredStates -> CaveContext (Maybe Agendum) +aStar agenda closed + -- | trace ("Peeping " ++ (show $ fst $ P.findMin agenda) ++ ": " ++ (show reached) ++ " <- " ++ (show $ toList $ Q.take 1 $ _trail $ currentAgendum) ++ " :: " ++ (show newAgenda)) False = undefined + -- | trace ("Peeping " ++ (show $ _current $ snd $ P.findMax agenda) ++ " : foundFlow " ++ (show $ _trailBenefit $ snd $ P.findMax agenda)) False = undefined + -- | trace ("Peeping " ++ (show $ _current $ snd $ P.findMax agenda) ++ " : foundFlow " ++ (show $ _trailBenefit $ snd $ P.findMax agenda) ++ " : trail " ++ (show $ _trail $ snd $ P.findMax agenda) ++ " : closed " ++ (show closed)) False = undefined + -- | trace ("Peeping " ++ (show $ P.findMax agenda)) False = undefined + | P.null agenda = return Nothing + | otherwise = + do let (_, currentAgendum) = P.findMax agenda + let reached = currentAgendum ^. current + nexts <- candidates currentAgendum closed + let newAgenda = foldl' (\q a -> P.insert (_benefit a) a q) (P.deleteMax agenda) nexts + reachedGoal <- isGoal currentAgendum + let cl = (reached, currentAgendum ^. trailBenefit) + if reachedGoal + then return (Just currentAgendum) + else if (cl `S.member` closed) + then aStar (P.deleteMax agenda) closed + else aStar newAgenda (S.insert cl closed) + +allSolutions :: Agenda -> ExploredStates -> PartSolutions -> CaveContext PartSolutions +allSolutions agenda closed foundSolutions + | P.null agenda = return foundSolutions + | otherwise = + do let (_, currentAgendum) = P.findMax agenda + let reached = currentAgendum ^. current + nexts <- candidates currentAgendum closed + let newAgenda = foldl' (\q a -> P.insert (_benefit a) a q) (P.deleteMax agenda) nexts + reachedGoal <- isGoal currentAgendum + let cl = (reached, currentAgendum ^. trailBenefit) + newFoundSolutions <- includeAgendum foundSolutions currentAgendum + if reachedGoal + then allSolutions (P.deleteMax agenda) closed newFoundSolutions + else if (cl `S.member` closed) + then allSolutions (P.deleteMax agenda) closed foundSolutions + else allSolutions newAgenda (S.insert cl closed) newFoundSolutions + + +candidates :: Agendum -> ExploredStates -> CaveContext (Q.Seq Agendum) +candidates agendum closed = + do let candidate = agendum ^. current + let previous = agendum ^. trail + let prevBenefit = agendum ^. trailBenefit + succs <- successors candidate + succAgs <- mapM (makeAgendum previous prevBenefit) succs + let nonloops = Q.filter (\s -> (s ^. current, s ^. trailBenefit) `S.notMember` closed) succAgs + return nonloops + +emptySearchState :: RoomID -> SearchState +emptySearchState startID = SearchState + { _currentRoom = startID + , _currentTime = 0 + , _openValves = S.empty + } + +currentFlow :: SearchState -> CaveContext Int +currentFlow state = + do cave <- asks getCave + let valves = state ^. openValves + let presentRooms = cave `M.restrictKeys` valves + return $ sumOf (folded . flowRate) presentRooms + +timeOf :: SearchState -> Int +timeOf state = state ^. currentTime + +successors :: SearchState -> CaveContext (Q.Seq SearchState) +successors state = + do isFF <- isFullFlow state + cave <- asks getCave + timeLimit <- asks getTimeLimit + let here = state ^. currentRoom + let opened = state ^. openValves + let now = state ^. currentTime + let remaining = S.toList $ S.filter (\t -> (t ^. tunnelTo) `S.notMember` opened) ((cave ! here) ^. tunnels) + let moves = [ SearchState + { _currentRoom = (t ^. tunnelTo) + , _currentTime = now + (t ^. tunnelLength) + , _openValves = opened + } + | t <- remaining + , now + (t ^. tunnelLength) <= timeLimit + ] + let opens = if here `S.notMember` opened && (cave ! here) ^. flowRate > 0 && now < timeLimit + then [SearchState { _currentRoom = here, _currentTime = now + 1, _openValves = S.insert here opened }] + else [] + let nexts = if null opens then moves else opens + let nexts' = if null nexts + then [ SearchState + { _currentRoom = here + , _currentTime = timeLimit + , _openValves = opened + } ] + else nexts + let succs = Q.fromList nexts' + if isFF || (Q.null succs) + then return $ Q.singleton (state & currentTime .~ timeLimit) + else return succs + +estimateBenefit :: SearchState -> CaveContext Int +estimateBenefit here = + do cave <- asks getCave + timeLimit <- asks getTimeLimit + let timeRemaining = timeLimit - (timeOf here) + cf <- currentFlow here + sortedValves <- asks getSortedRooms + let opened = here ^. openValves + let sortedClosedValves = [(cave ! v) ^. flowRate | v <- sortedValves, v `S.notMember` opened] + let otherValveFlows = sum $ zipWith (*) [timeRemaining, (timeRemaining - 2) .. 0] sortedClosedValves + return $ (cf * timeRemaining) + otherValveFlows + +makeAgendum :: Q.Seq SearchState -> Int -> SearchState -> CaveContext Agendum +makeAgendum previous prevBenefit newState = + do predicted <- estimateBenefit newState -- (Q.length previous) + -- cf <- currentFlow newState + oldFlow <- lastFlow previous (timeOf newState) + let newTrail = previous |> newState + let incurred = prevBenefit + oldFlow + return Agendum { _current = newState + , _trail = newTrail + , _trailBenefit = incurred + , _benefit = incurred + predicted + } + +lastFlow :: Q.Seq SearchState -> Int -> CaveContext Int +lastFlow Q.Empty _ = return 0 +lastFlow (_ :|> previous) newTime = + do cf <- currentFlow previous + let dt = newTime - (timeOf previous) + return (cf * dt) + +isGoal :: Agendum -> CaveContext Bool +isGoal agendum = + do timeLimit <- asks getTimeLimit + let s = agendum ^. current + return $ (timeOf s) == timeLimit + +isFullFlow :: SearchState -> CaveContext Bool +isFullFlow state = + do cave <- asks getCave + cf <- currentFlow state + let ff = sumOf (folded . flowRate) cave + return (cf == ff) + +compress :: Cave -> Cave +compress cave = M.mapWithKey (compressRoom cave) cave + +compressRoom :: Cave -> RoomID -> Room -> Room +compressRoom cave here room = room & tunnels .~ t' + where t' = reachableFrom cave [Tunnel here 0] S.empty S.empty + +reachableFrom :: Cave -> [Tunnel] -> S.Set RoomID -> S.Set Tunnel -> S.Set Tunnel +reachableFrom _ [] _ routes = routes +reachableFrom cave (tunnel@(Tunnel here len):boundary) found routes + | here `S.member` found = reachableFrom cave boundary found routes + | otherwise = reachableFrom cave (boundary ++ (S.toList legs)) (S.insert here found) routes' + where exits = (cave ! here) ^. tunnels + exits' = S.filter (\t -> (t ^. tunnelTo) `S.notMember` found) exits + legs = S.map (\t -> t & tunnelLength .~ (len + 1)) exits' + routes' = if (len == 0) || ((cave ! here) ^. flowRate) == 0 + then routes + else S.insert tunnel routes + +-- Parse the input file + +caveP :: Parser Cave +valveP :: Parser (RoomID, Room) +roomP :: Parser Room +tunnelsP :: Parser (S.Set Tunnel) +tunnelTextP :: Parser Text + +caveP = M.fromList <$> valveP `sepBy` endOfLine +valveP = (,) <$> ("Valve " *> (many1 letter)) <*> roomP +roomP = Room <$> (" has flow rate=" *> decimal) <*> (tunnelTextP *> tunnelsP) + -- where roomify v ts = Room {flowRate = v, tunnels = ts } +tunnelsP = (S.fromList . (fmap (flip Tunnel 1))) <$> (many1 letter) `sepBy` ", " +tunnelTextP = "; tunnels lead to valves " <|> "; tunnel leads to valve " + +successfulParse :: Text -> Cave +successfulParse input = + case parseOnly caveP input of + Left _err -> M.empty -- TIO.putStr $ T.pack $ parseErrorPretty err + Right cave -> cave \ No newline at end of file diff --git a/advent16/a16-solution.dot.png b/advent16/a16-solution.dot.png new file mode 100644 index 0000000000000000000000000000000000000000..a27adfadc48a993334f73d0c3d1bb409fa33f812 GIT binary patch literal 202269 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