Files
newt/aoc2024/Day4.newt
2024-12-05 16:13:12 -08:00

77 lines
2.1 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 Day4
import Prelude
import Node
import Aoc
data Problem : U where
P : Int String Problem
get : Problem Int Int Char
get (P size text) r c =
if r < 0 || size <= r then '.'
else if c < 0 || size <= c then '.'
else sindex text (r * (size + 1) + c)
check : Problem Int Int Int × Int Int
check prob r c (dr,dc) =
if (get prob r c) /= 'X' then 0
else if (get prob (r + dr) (c + dc)) /= 'M' then 0
else if (get prob (r + 2 * dr) (c + 2 * dc)) /= 'A' then 0
else if (get prob (r + 3 * dr) (c + 3 * dc)) /= 'S' then 0
else 1
dirs : List (Int × Int)
dirs = tail $ _,_ <$> 0 :: 0 - 1 :: 1 :: Nil <*> 0 :: 0 - 1 :: 1 :: Nil
part1 : Problem Int
part1 (P size text) = go 0 0 0
where
go : Int Int Int Int
go acc r c =
if r == size then acc else
if c == size then go acc (r + 1) 0 else
let acc = foldl _+_ acc $ map (check (P size text) r c) dirs in
go acc r (c + 1)
pats : List (Char × Char × Char × Char)
pats = ('M', 'M', 'S', 'S') ::
('S', 'M', 'M', 'S') ::
('S', 'S', 'M', 'M') ::
('M', 'S', 'S', 'M') ::
Nil
check2 : Problem Int Int (Char × Char × Char × Char) Int
check2 prob r c (w,x,y,z) =
if (get prob r c) /= 'A' then 0
else if (get prob (r - 1) (c - 1)) /= w then 0
else if (get prob (r - 1) (c + 1)) /= x then 0
else if (get prob (r + 1) (c + 1)) /= y then 0
else if (get prob (r + 1) (c - 1)) /= z then 0
else 1
part2 : Problem Int
part2 (P size text) = go 0 0 0
where
go : Int Int Int Int
go acc r c =
if r == size then acc else
if c == size then go acc (r + 1) 0 else
let acc = foldl _+_ acc $ map (check2 (P size text) r c) pats in
go acc r (c + 1)
run : String -> IO Unit
run fn = do
putStrLn fn
text <- readFile fn
let lines = split (trim text) "\n"
-- I'm going to assume it's square for convenience
let size = length lines
printLn $ "part1 " ++ show (part1 $ P (cast size) text)
printLn $ "part2 " ++ show (part2 $ P (cast size) text)
main : IO Unit
main = do
run "aoc2024/day4/eg.txt"
run "aoc2024/day4/input.txt"