Files
newt/aoc2025/Day4.newt
2025-12-03 22:12:40 -08:00

80 lines
2.2 KiB
Agda
Raw Permalink 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 Day4
import Prelude
import Node
import Aoc
import Data.SortedMap
gridPoints : String List (Char × Int × Int)
gridPoints text = go 0 0 (unpack text) Nil
where
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)
Grid : U
Grid = SortedMap Point Int
getGrid : String Grid
getGrid text = foldl update (EmptyMap compare) $ gridPoints text
where
update : Grid Char × Point Grid
update grid (c,pt) = updateMap pt (ord c) grid
neighbors : Point List Point
neighbors pt = map (_+_ pt) (
(0 - 1, 0 - 1) :: (0 - 1, 0) :: (0 - 1, 1) ::
(0, 0 - 1) :: (0, 1) ::
(1, 0 - 1) :: (1, 0) :: (1, 1) :: Nil)
part1 : Grid Int
part1 grid = go 0 $ toList grid
where
full : Maybe Int Bool
full (Just 64) = True
full _ = False
go : Int List (Point × Int) Int
go acc Nil = acc
go acc ((pt,64) :: rest) =
let count = length' $ filter full $ map (flip lookupMap' grid) $ neighbors pt
in if count < 4 then go (acc + 1) rest else go acc rest
go acc (_ :: rest) = go acc rest
part2 : Grid Int
part2 grid =
let todo = filter (\ x => snd x == 64) $ toList grid
in go todo emptyMap grid
where
full : (Point × Int) Bool
full (_, 64) = True
full _ = False
helper : Grid (Point × Int) Grid
helper todo (k, v) = updateMap k v todo
go : List (Point × Int) Grid Grid Int
go Nil todo grid = do
case toList todo of
Nil => length' $ filter (\ x => snd x == 0) $ toList {Point} {Int} grid
todo => go todo emptyMap grid
go ((pt, _) :: xs) todo grid = do
let pts = filter full $ mapMaybe (flip lookupMap grid) $ neighbors pt
if length' pts < 4
then go xs (foldl helper todo pts) (updateMap pt 0 grid)
else go xs todo grid
run : String -> IO Unit
run fn = do
putStrLn fn
text <- readFile fn
let grid = getGrid text
putStrLn $ "part1 " ++ show (part1 grid)
putStrLn $ "part2 " ++ show (part2 grid)
main : IO Unit
main = do
run "aoc2025/day4/eg.txt"
run "aoc2025/day4/input.txt"