Files
newt/aoc2025/Day6.newt
2025-12-05 22:46:16 -08:00

75 lines
2.0 KiB
Agda
Raw Blame History

module Day6
import Prelude
import Node
import Aoc
data Oper = Plus | Times
getOp : Char Maybe Oper
getOp '+' = Just Plus
getOp '*' = Just Times
getOp _ = Nothing
head' : a. List a Maybe a
head' (x :: xs) = Just x
head' _ = Nothing
transpose : a. List (List a) List (List a)
transpose {a} Nil = Nil
transpose {a} (Nil :: xs) = Nil
transpose {a} xs = mapMaybe head' xs :: transpose (map tail xs)
calc : List (List Int) List Oper Int
calc rows ops = foldl _+_ 0 $ map go $ zip ops $ rows
where
go : Oper × List Int Int
go (Plus, nums) = foldl _+_ 0 nums
go (Times, nums) = foldl _*_ 1 nums
part1 : String Int
part1 text =
let lines = split (trim text) "\n" in
case reverse lines of
Nil => -1
last :: rest =>
let key = unpack last
in calc (transpose (map (splitLine 0 key unpack) rest)) $ mapMaybe getOp key
where
splitLine : Int List Char List Char List Int
splitLine acc (a :: b :: cs) (d :: ds) =
if b == ' '
then let acc = if d == ' ' then acc else acc * 10 + (ord d - 48)
in splitLine acc (b :: cs) ds
else acc :: splitLine 0 (b :: cs) ds
splitLine acc _ (d :: ds) =
let acc = if d == ' ' then acc else acc * 10 + (ord d - 48)
in splitLine acc Nil ds
splitLine acc _ Nil = acc :: Nil
part2 : String Int
part2 text =
let lines = split (trim text) "\n" in
case reverse lines of
Nil => -1
last :: rest =>
let key = unpack last
in calc (splitOn 0 $ map (packNum 0) $ transpose $ map unpack $ reverse rest) $ mapMaybe getOp key
where
packNum : Int List Char Int
packNum acc Nil = acc
packNum acc (' ' :: cs) = packNum acc cs
packNum acc (c :: cs) = packNum (acc * 10 + (ord c - 48)) cs
run : String -> IO Unit
run fn = do
putStrLn fn
text <- readFile fn
putStrLn $ "part1 \{show $ part1 text}"
putStrLn $ "part2 \{show $ part2 text}"
main : IO Unit
main = do
run "aoc2025/day6/eg.txt"
run "aoc2025/day6/input.txt"