From: Neil Smith Date: Fri, 20 Dec 2024 11:34:28 +0000 (+0000) Subject: Done day 20 part 2 X-Git-Url: https://git.njae.me.uk/?a=commitdiff_plain;h=295b8f7a9119ef9198372d52362d3cf8e07cbbf4;p=advent-of-code-24.git Done day 20 part 2 --- diff --git a/advent20/Main.hs b/advent20/Main.hs index 93f5dc8..91f94a6 100644 --- a/advent20/Main.hs +++ b/advent20/Main.hs @@ -27,15 +27,17 @@ main = do dataFileName <- getDataFileName text <- readFile dataFileName let track = mkTrack text - print track + -- print track let costsFromStart = costsFrom track (M.singleton track.start 0) (M.singleton track.start 0) let costsFromGoal = costsFrom track (M.singleton track.goal 0) (M.singleton track.goal 0) -- print costsFromStart -- print costsFromGoal - -- print $ fmap (\h -> (h, pathCostWithCheat track costsFromStart costsFromGoal h)) $ S.toList track.walls - -- print $ allCheatedCosts track costsFromStart costsFromGoal - print $ findSavings track costsFromStart costsFromGoal + -- print $ fmap (\h -> (h, pathCostWithCheat 2 track costsFromStart costsFromGoal h)) $ M.keys costsFromStart + -- print $ allCheatedCosts 2 track costsFromStart costsFromGoal + -- print $ findSavings 2 track costsFromStart costsFromGoal + -- print $ findSavings 20 track costsFromStart costsFromGoal print $ part1 track costsFromStart costsFromGoal + print $ part2 track costsFromStart costsFromGoal -- let allTrails = allRoutesFrom maze -- -- print allTrails -- print $ part1 allTrails @@ -44,16 +46,21 @@ main = -- part1, part2 :: [Agendum] -> Int -- part1 trails = cost $ head trails -findSavings track costsFromStart costsFromGoal = fmap (\g -> (length g, head g)) $ group $ sort savings +findSavings cheatLen track costsFromStart costsFromGoal = fmap (\g -> (length g, head g)) $ group $ sort savings where fullCost = costsFromStart M.! track.goal - cheatCosts = allCheatedCosts track costsFromStart costsFromGoal + cheatCosts = allCheatedCosts cheatLen track costsFromStart costsFromGoal savings = filter (> 0) $ fmap (\c -> fullCost - c) cheatCosts part1 track costsFromStart costsFromGoal = length savings where fullCost = costsFromStart M.! track.goal - cheatCosts = allCheatedCosts track costsFromStart costsFromGoal + cheatCosts = allCheatedCosts 2 track costsFromStart costsFromGoal + savings = filter (>= 100) $ fmap (\c -> fullCost - c) cheatCosts +part2 track costsFromStart costsFromGoal = length savings + where fullCost = costsFromStart M.! track.goal + cheatCosts = allCheatedCosts 20 track costsFromStart costsFromGoal savings = filter (>= 100) $ fmap (\c -> fullCost - c) cheatCosts + mkTrack :: String -> Track mkTrack text = Track { walls = walls, start = start, goal = goal } where rows = lines text @@ -70,10 +77,10 @@ showTrackWithCheat track here = unlines $ fmap showRow [0..rMax] cMax = maximum $ fmap (\(V2 _ c) -> c) $ S.toList $ walls track showRow r = [ showCell (V2 r c) | c <- [0..cMax] ] showCell pos - | pos == here = '@' + | pos == here = '□' | pos == start track = 'S' | pos == goal track = 'E' - | pos `S.member` walls track = '☐' + | pos `S.member` walls track = '■' | otherwise = '.' costsFrom :: Track -> TrackCost -> TrackCost -> TrackCost @@ -93,16 +100,25 @@ neighbours track here = here ^+^ V2 1 0, here ^+^ V2 (-1) 0 ] -allCheatedCosts track costsFromStart costsFromGoal = - catMaybes [ pathCostWithCheat track costsFromStart costsFromGoal h - | h <- S.toList track.walls +allCheatedCosts cheatLen track costsFromStart costsFromGoal = + concat [ pathCostWithCheat cheatLen track costsFromStart costsFromGoal h + | h <- M.keys costsFromStart ] -pathCostWithCheat :: Track -> TrackCost -> TrackCost -> Position -> Maybe Int -pathCostWithCheat track costsFromStart costsFromGoal here - | (not $ null costsToStart) && (not $ null costsToGoal) = Just $ minimum costsToStart + minimum costsToGoal + 2 - | otherwise = Nothing +pathCostWithCheat :: Int -> Track -> TrackCost -> TrackCost -> Position -> [Int] +pathCostWithCheat cheatLen track costsFromStart costsFromGoal here = + fmap (+ costsFromStart M.! here) continueCosts where - nbrs = neighbours track here - costsToStart = catMaybes $ fmap (`M.lookup` costsFromStart) nbrs - costsToGoal = catMaybes $ fmap (`M.lookup` costsFromGoal) nbrs + nbrs = [ here ^+^ (V2 dr dc) + | dr <- [-cheatLen .. cheatLen] + , dc <- [-cheatLen .. cheatLen] + , abs dr + abs dc <= cheatLen + ] + continueCosts = catMaybes $ fmap contCost nbrs + contCost :: Position -> Maybe Int + contCost nbr = do gc <- M.lookup nbr costsFromGoal + let sc = l2Dist nbr here + return $ gc + sc + +l2Dist :: Position -> Position -> Int +l2Dist (V2 r1 c1) (V2 r2 c2) = abs (r1 - r2) + abs (c1 - c2) diff --git a/adventofcode24.cabal b/adventofcode24.cabal index 5e148df..32d0480 100644 --- a/adventofcode24.cabal +++ b/adventofcode24.cabal @@ -198,4 +198,4 @@ executable advent19a executable advent20 import: warnings, common-extensions, build-directives, common-modules main-is: advent20/Main.hs - build-depends: containers, linear \ No newline at end of file + build-depends: containers, linear