Files
newt/aoc2024/Day8.newt

81 lines
2.1 KiB
Agda
Raw Blame History

module Day8
import Prelude
import Node
import Aoc
import SortedMap
Ant : U
Ant = Char × Int × Int
-- This should be a utility...
parse : String List Ant
parse text = go 0 0 (unpack text) Nil
where
-- might as well be tail recursive
go : Int Int List Char List Ant List Ant
go row col Nil ants = ants
go row col ('\n' :: cs) ants = go (row + 1) 0 cs ants
go row col (c :: cs) ants = go row (col + 1) cs ((c,row,col) :: ants)
doPair : Point Point List Point
doPair x y = let d = y - x in y + d :: x - d :: Nil
doGroup : List Ant -> List Point
doGroup (x :: xs) = join $ doGroup xs :: map (doPair (snd x) snd) xs
doGroup Nil = Nil
group : List Ant (List Ant) List (List Ant)
group (a :: as) Nil = group as (a :: Nil)
group (a :: as) (b :: bs) =
if fst a == fst b
then group as (a :: b :: bs)
else (b :: bs) :: group as (a :: Nil)
group Nil bs = bs :: Nil
max : Int Int Int
max a b = if a < b then b else a
check : Int Point Bool
check mr (r,c) = 0 <= r && 0 <= c && r <= mr && c <= mr
doPair2 : Int -> Point Point List Point
doPair2 m x y = go x (y - x) ++ go y (x - y)
where
go : Point -> Point -> List Point
go pt d = if check m pt then pt :: go (pt + d) d else Nil
doGroup2 : Int -> List Ant -> List Point
doGroup2 m (x :: xs) = join $ doGroup2 m xs :: map (doPair2 m (snd x) snd) xs
doGroup2 m Nil = Nil
run : String -> IO Unit
run fn = do
putStrLn fn
text <- readFile fn
let points = parse text
let maxrow = trace "maxrow" $ foldl max 0 $ map (fst snd) points
let maxcol = trace "maxcol" $ foldl max 0 $ map (snd snd) points
let ants = filter (\ pt => fst pt /= '.') points
let ants = qsort (\ x y => fst x < fst y) ants
let groups = group ants Nil
let stuff = join $ map doGroup groups
let nodes = filter (check maxrow) stuff
let part1 = length $ ordNub nodes
putStrLn $ "part1 " ++ show part1
let stuff2 = join $ map (doGroup2 maxrow) groups
let part2 = length $ ordNub stuff2
putStrLn $ "part2 " ++ show part2
main : IO Unit
main = do
run "aoc2024/day8/eg.txt"
run "aoc2024/day8/input.txt"