day 16 part 1

This commit is contained in:
Quinten Kock 2022-12-16 12:09:06 +01:00
parent 05a81eb063
commit fdd09b72c7
3 changed files with 167 additions and 0 deletions

101
2022/day16.hs Normal file
View File

@ -0,0 +1,101 @@
import qualified Data.Map as M
import qualified Data.Set as S
import Data.List.Split (splitOn)
import Debug.Trace (traceShowId, traceShow, trace)
import Data.Maybe (fromMaybe)
import Bfs
import Data.List (maximumBy, permutations, delete)
import Data.Function (on)
data Valve = V { flow' :: Int, neighs' :: [String] } deriving Show
type ZMap = M.Map String Valve
data NzValve = NV { flow :: Int, dists :: M.Map String Int} deriving Show
type NzMap = M.Map String NzValve
parseValve :: String -> (String, Valve)
parseValve xs = (name, V flow tunnels) where
name = words xs !! 1
flow = read $ last $ splitOn "=" (head $ splitOn ";" xs)
valves = splitOn ", " $ last (splitOn "tunnels lead to valves " xs)
singleValve = splitOn "tunnel leads to valve " xs
tunnels = if length singleValve == 1 then valves else [last singleValve]
search' :: ZMap -> String -> String -> Int
search' scan from to = dists M.! to where
dists = bfs f [(from,0)] M.empty
f x = neighs' (scan M.! x)
prepass :: ZMap -> NzMap
prepass xs = M.fromList $ concatMap f $ M.toList xs where
f (name, v@(V flow _)) = [(name, NV flow (M.fromList $ dists name)) | name == "AA" || flow > 0]
dists name = map (\target -> (target, search' xs name target)) (filter (/= name) allValves)
allValves = map fst . filter (\(name, V flow _) -> name == "AA" || flow > 0) $ M.toList xs
type Memo = M.Map (S.Set String, String, Int) Int
-- search :: Map -> S.Set String -> String -> Int -> Memo -> (Int, Memo)
-- search scan active location n memo
-- | n <= 0 = (0, M.empty)
-- | otherwise = (releasedPressure + fst best, snd best) where
-- valve = scan M.! location
-- openValve = [(S.insert location active, location, n-1) | S.notMember location active && flow valve > 0]
-- releasedPressure = sum $ map (flow . (scan M.!)) (S.toList active)
-- nop = [(active, location, n-1) | S.size active == M.size scan]
-- move = map (\(name, dist) -> (active, name, n-dist)) (dists $ scan M.! location)
-- actions = openValve ++ move ++ nop
-- trace x = if n>=15 then traceShow (fst x) x else x
-- best = trace $ maximumBy (compare `on` fst) $ map (\(a,l,n) -> search scan a l n memo) actions
-- -- best = maybe best' (\b -> (b,memo)) (M.lookup (active, location, n) memo)
-- -- best' = foldr f (0, memo) actions where
-- -- f (a,l, newN) (i,m) = let (result, memo') = search scan a l newN m; b = max i result in
-- -- trace (b, M.insertWith max (a,l, newN) b $ M.unionWith max m memo')
perms :: Int -> NzMap -> [[String]]
perms limit m = perms' "AA" limit elems where
elems = filter (/= "AA") $ M.keys m
perms' :: String -> Int -> [String] -> [[String]]
perms' current remaining [] = [[]]
perms' current remaining as = do
a <- as
let distance = dists (m M.! current) M.! a
if distance < remaining then do
let l = delete a as
ls <- perms' a (remaining-distance) l
pure $ a:ls
else pure [a]
execPerm :: NzMap -> [String] -> Int -> String -> Int -> Int
execPerm nzmap [] flowrate location remaining = remaining * flowrate
execPerm nzmap (target:qs) flowrate location remaining
| remaining < 0 = 0
| distance >= remaining = remaining * flowrate
| otherwise = (distance * flowrate) + execPerm nzmap qs flowrate' target (remaining - distance)
where
valve = nzmap M.! location
distance = 1 + dists valve M.! target
flowrate' = flowrate + flow (nzmap M.! target)
traceMap :: (Show a, Show b) => (a -> a -> Bool) -> (a -> b) -> [a] -> [b]
traceMap cond f [] = []
traceMap cond f [x] = [f x]
traceMap cond f (x:y:xs)
| cond x y = let result = f x in traceShow (result, x) (result: traceMap cond f (y:xs))
| otherwise = f x : traceMap cond f (y:xs)
main :: IO ()
main = do
x <- prepass . M.fromList . map parseValve . lines <$> getContents
mapM_ print x
let all = perms 30 x
let exec p = execPerm x p 0 "AA" 30
let result = traceMap (\a b -> take 2 a /= take 2 b) exec all
putStr "part 1: "
print $ maximum result
-- print $ fst $ search x S.empty "AA" 30 M.empty

56
2022/inputs/day16 Normal file
View File

@ -0,0 +1,56 @@
Valve JI has flow rate=21; tunnels lead to valves WI, XG
Valve DM has flow rate=3; tunnels lead to valves JX, NG, AW, BY, PF
Valve AZ has flow rate=0; tunnels lead to valves FJ, VC
Valve YQ has flow rate=0; tunnels lead to valves TE, OP
Valve WI has flow rate=0; tunnels lead to valves JI, VC
Valve NE has flow rate=0; tunnels lead to valves ZK, AA
Valve FM has flow rate=0; tunnels lead to valves LC, DU
Valve QI has flow rate=0; tunnels lead to valves TE, JW
Valve OY has flow rate=0; tunnels lead to valves XS, VF
Valve XS has flow rate=18; tunnels lead to valves RR, OY, SV, NQ
Valve NU has flow rate=0; tunnels lead to valves IZ, BD
Valve JX has flow rate=0; tunnels lead to valves DM, ZK
Valve WT has flow rate=23; tunnels lead to valves OV, QJ
Valve KM has flow rate=0; tunnels lead to valves TE, OL
Valve NG has flow rate=0; tunnels lead to valves II, DM
Valve FJ has flow rate=0; tunnels lead to valves AZ, II
Valve QR has flow rate=0; tunnels lead to valves ZK, KI
Valve KI has flow rate=9; tunnels lead to valves ZZ, DI, TL, AJ, QR
Valve ON has flow rate=0; tunnels lead to valves LC, QT
Valve AW has flow rate=0; tunnels lead to valves DM, AA
Valve HI has flow rate=0; tunnels lead to valves TE, VC
Valve XG has flow rate=0; tunnels lead to valves II, JI
Valve II has flow rate=19; tunnels lead to valves LF, NG, OL, FJ, XG
Valve VC has flow rate=24; tunnels lead to valves WI, HI, AZ
Valve VJ has flow rate=0; tunnels lead to valves UG, AA
Valve IZ has flow rate=0; tunnels lead to valves VF, NU
Valve EJ has flow rate=0; tunnels lead to valves ZK, LC
Valve DU has flow rate=12; tunnels lead to valves TC, UG, FM
Valve ZK has flow rate=10; tunnels lead to valves JX, EJ, JW, QR, NE
Valve XF has flow rate=25; tunnels lead to valves OP, VT
Valve LC has flow rate=4; tunnels lead to valves FM, EJ, ON, AJ, PF
Valve SV has flow rate=0; tunnels lead to valves XS, IY
Valve LF has flow rate=0; tunnels lead to valves II, OV
Valve DI has flow rate=0; tunnels lead to valves KI, BY
Valve OP has flow rate=0; tunnels lead to valves YQ, XF
Valve NQ has flow rate=0; tunnels lead to valves TC, XS
Valve QJ has flow rate=0; tunnels lead to valves VT, WT
Valve IY has flow rate=22; tunnel leads to valve SV
Valve AJ has flow rate=0; tunnels lead to valves LC, KI
Valve TE has flow rate=11; tunnels lead to valves QI, HI, KM, YQ
Valve ZZ has flow rate=0; tunnels lead to valves KI, AA
Valve VT has flow rate=0; tunnels lead to valves XF, QJ
Valve OL has flow rate=0; tunnels lead to valves KM, II
Valve TC has flow rate=0; tunnels lead to valves NQ, DU
Valve TL has flow rate=0; tunnels lead to valves VF, KI
Valve QT has flow rate=0; tunnels lead to valves AA, ON
Valve BY has flow rate=0; tunnels lead to valves DM, DI
Valve OV has flow rate=0; tunnels lead to valves LF, WT
Valve VN has flow rate=0; tunnels lead to valves RR, BD
Valve VF has flow rate=13; tunnels lead to valves OY, IZ, TL
Valve BD has flow rate=17; tunnels lead to valves NU, VN
Valve UG has flow rate=0; tunnels lead to valves VJ, DU
Valve PF has flow rate=0; tunnels lead to valves LC, DM
Valve RR has flow rate=0; tunnels lead to valves XS, VN
Valve AA has flow rate=0; tunnels lead to valves QT, ZZ, AW, VJ, NE
Valve JW has flow rate=0; tunnels lead to valves ZK, QI

10
2022/inputs/day16.test Normal file
View File

@ -0,0 +1,10 @@
Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
Valve BB has flow rate=13; tunnels lead to valves CC, AA
Valve CC has flow rate=2; tunnels lead to valves DD, BB
Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
Valve EE has flow rate=3; tunnels lead to valves FF, DD
Valve FF has flow rate=0; tunnels lead to valves EE, GG
Valve GG has flow rate=0; tunnels lead to valves FF, HH
Valve HH has flow rate=22; tunnel leads to valve GG
Valve II has flow rate=0; tunnels lead to valves AA, JJ
Valve JJ has flow rate=21; tunnel leads to valve II