Files
aoc2024/src/Day20.hs
2024-12-20 22:27:24 +05:30

57 lines
1.4 KiB
Haskell

module Main where
import qualified Data.IntMap as IM
import qualified Data.Map as M
type Coord = (Int, Int)
type Grid = M.Map Coord Char
type Path = IM.IntMap Coord
manhattan :: Coord -> Coord -> Int
manhattan (x1, y1) (x2, y2) = abs (x2 - x1) + abs (y2 - y1)
neighbours :: Coord -> [Coord]
neighbours (x, y) = [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]
race :: Grid -> Coord -> Path
race grid = IM.fromList . zip [0 ..] . path (-1, -1)
where
path :: Coord -> Coord -> [Coord]
path prev c = case ch of
'E' -> [c, next]
'.' -> c : path c next
where
[(next, ch)] =
[ (n, ch)
| n <- neighbours c,
n /= prev,
let Just ch = n `M.lookup` grid,
ch /= '#'
]
nCheats :: Path -> Int -> Int
nCheats path n =
let l = IM.size path
in length
[ ()
| i <- [0 .. l - 1],
j <- [i + 100 .. l - 1],
let d = manhattan (path IM.! i) (path IM.! j),
d <= n,
100 <= j - i - d
]
main :: IO ()
main =
do
raw <- lines <$> readFile "./inputs/day20.in"
let [start] = [(x, y) | (y, row) <- zip [0 ..] raw, (x, ch) <- zip [0 ..] row, ch == 'S']
grid = M.fromList [((x, y), ch) | (y, row) <- zip [0 ..] raw, (x, ch) <- zip [0 ..] row]
path = race grid start
putStr "Part 1: " >> print (nCheats path 2)
putStr "Part 2: " >> print (nCheats path 20)