Files
newt/aoc2024/Day10.newt

82 lines
2.3 KiB
Agda
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
module Day10
import Prelude
import Node
import Aoc
import SortedMap
-- move to lib
gridPoints : String List (Char × Int × Int)
gridPoints text = go 0 0 (unpack text) Nil
where
-- might as well be tail recursive
go : Int Int List Char List (Char × Int × Int) List (Char × Int × Int)
go row col Nil points = points
go row col ('\n' :: cs) points = go (row + 1) 0 cs points
go row col (c :: cs) points = go row (col + 1) cs ((c,row,col) :: points)
-- TODO add parameter a and pass Char -> a into getGrid
Grid : U
Grid = SortedMap Point Int
digitToInt : Char Int
digitToInt c = ord c - 48
getGrid : String Grid
getGrid text = foldl update EmptyMap $ gridPoints text
where
update : Grid Char × Point Grid
update grid (c,pt) = updateMap pt (digitToInt c) grid
peers : Point List Point
peers pt = map (_+_ pt) ((0, 0 - 1) :: (0,1) :: (0 - 1,0) :: (1,0) :: Nil)
paths : Grid List Point Int Int
paths grid pts ht =
if ht == 9 then cast $ length pts else
-- Maybe I should nub with a sortedMap
let cands = ordNub $ map fst $ filter (_==_ (ht + 1) snd) $ join $ map getCands pts
in paths grid cands (ht + 1)
where
getCands : Point List (Point × Int)
getCands pt = mapMaybe (\ p => lookupMap p grid) (peers pt)
paths2 : Grid List (Point × Int) Int Int
paths2 grid pts ht =
if ht == 9 then foldl _+_ 0 $ map snd $ pts else
let cands = join $ map getCands pts
pts' = toList $ foldMap _+_ EmptyMap cands
in paths2 grid pts' (ht + 1)
where
getCands : Point × Int List (Point × Int)
getCands (pt,cnt) =
map (\ x => fst x , cnt)
$ filter (_==_ (ht + 1) snd)
$ mapMaybe (\ p => lookupMap p grid) (peers pt)
run : String -> IO Unit
run fn = do
putStrLn fn
text <- readFile fn
let grid = getGrid text
let starts = filter (_==_ 0 snd) $ toList grid
let all = map (\ pt => paths grid (fst pt :: Nil) 0) starts
let part1 = foldl _+_ 0 all
putStrLn $ "part1 " ++ show part1
let all = map (\ pt => paths2 grid ((fst pt, 1) :: Nil) 0) starts
let part2 = foldl _+_ 0 all
putStrLn $ "part2 " ++ show part2
main : IO Unit
main = do
run "aoc2024/day10/eg.txt"
run "aoc2024/day10/eg2.txt"
run "aoc2024/day10/eg3.txt"
run "aoc2024/day10/eg4.txt"
run "aoc2024/day10/eg5.txt"
run "aoc2024/day10/input.txt"