--- Writeup at https://work.njae.me.uk/2024/12/16/advent-of-code-2024-day-16/
+-- Writeup at https://work.njae.me.uk/2024/12/20/advent-of-code-2024-day-20/
import AoC
-- import Data.Char
-import Linear (V2(..), (^+^), perp)
+import Linear (V2(..), (^+^))
import qualified Data.Set as S
import qualified Data.Map.Strict as M
import Data.Maybe
-import Data.List
+-- import Data.List
type Position = V2 Int -- r, c
-- 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
- -- print $ part2 allTrails
-
--- part1, part2 :: [Agendum] -> Int
--- part1 trails = cost $ head trails
-
-findSavings cheatLen 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 cheatLen track costsFromStart costsFromGoal
+-- savings = filter (> 0) $ fmap (\c -> fullCost - c) cheatCosts
+
+part1, part2 :: Track -> TrackCost -> TrackCost -> Int
+part1 = bigSavings 2 100
+part2 = bigSavings 20 100
+-- where fullCost = costsFromStart M.! track.goal
+-- 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
+
+bigSavings :: Int -> Int -> Track -> TrackCost -> TrackCost -> Int
+bigSavings cheatLen savingThreshold track costsFromStart costsFromGoal = length savings
where fullCost = costsFromStart M.! track.goal
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 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
+ savings = filter (>= savingThreshold) $ fmap (\c -> fullCost - c) cheatCosts
mkTrack :: String -> Track
[ here ^+^ V2 0 1, here ^+^ V2 0 (-1),
here ^+^ V2 1 0, here ^+^ V2 (-1) 0 ]
-
+allCheatedCosts :: Int -> Track -> TrackCost -> TrackCost -> [Int]
allCheatedCosts cheatLen track costsFromStart costsFromGoal =
concat [ pathCostWithCheat cheatLen track costsFromStart costsFromGoal h
| h <- M.keys costsFromStart