52 lines
1.1 KiB
Agda
52 lines
1.1 KiB
Agda
module Day2
|
|
|
|
import Prelude
|
|
import Node
|
|
import Aoc
|
|
|
|
decr : List Int → Bool
|
|
decr (x :: y :: _) = y < x
|
|
decr _ = False
|
|
|
|
diff : Int → Int → Int
|
|
diff x y = if x < y then y - x else x - y
|
|
|
|
isSafe : Bool → List Int → Bool
|
|
isSafe decr (x :: y :: rest) =
|
|
let d = diff x y
|
|
good = 0 < d && d < 4
|
|
safe = if x < y then not decr && good else decr && good in
|
|
if safe then isSafe decr (y :: rest) else False
|
|
isSafe _ _ = True
|
|
|
|
check : List Int → Bool
|
|
check x = isSafe (decr x) x
|
|
|
|
any : ∀ a. (a → Bool) → List a → Bool
|
|
any f xs = foldl (_||_) False $ map f xs
|
|
|
|
alts : List Int → List (List Int)
|
|
alts Nil = Nil
|
|
alts (x :: xs) = xs :: map (_::_ x) (alts xs)
|
|
|
|
-- I want lean's #eval here
|
|
|
|
parse : String → List (List Int)
|
|
parse text = map nums $ split (trim text) "\n"
|
|
|
|
run : String -> IO Unit
|
|
run fn = do
|
|
putStrLn fn
|
|
text <- readFile fn
|
|
let stuff = parse text
|
|
let good = filter check stuff
|
|
putStrLn $ "part1 " ++ show (length good)
|
|
let good = filter (any check ∘ alts) stuff
|
|
putStrLn $ "part2 " ++ show (length good)
|
|
|
|
main : IO Unit
|
|
main = do
|
|
run "aoc2024/day2/eg.txt"
|
|
run "aoc2024/day2/input.txt"
|
|
|