Day 9
This commit is contained in:
@@ -6,6 +6,9 @@ import Prelude
|
|||||||
nums' : String → String → List Int
|
nums' : String → String → List Int
|
||||||
nums' by s = map stringToInt $ filter (_/=_ "") $ split (trim s) by
|
nums' by s = map stringToInt $ filter (_/=_ "") $ split (trim s) by
|
||||||
|
|
||||||
|
min : ∀ a. {{Ord a}} → a → a → a
|
||||||
|
min x y = if x < y then x else y
|
||||||
|
|
||||||
max : ∀ a. {{Ord a}} → a → a → a
|
max : ∀ a. {{Ord a}} → a → a → a
|
||||||
max a b = if a < b then b else a
|
max a b = if a < b then b else a
|
||||||
|
|
||||||
|
|||||||
95
aoc2025/Day9.newt
Normal file
95
aoc2025/Day9.newt
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
module Day9
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
import Node
|
||||||
|
import Aoc
|
||||||
|
|
||||||
|
parsePoint : String → Maybe Point
|
||||||
|
parsePoint text = case split text "," of
|
||||||
|
a :: b :: Nil => Just (stringToInt a, stringToInt b)
|
||||||
|
_ => Nothing
|
||||||
|
|
||||||
|
parse : String → List Point
|
||||||
|
parse text = mapMaybe parsePoint $ split (trim text) "\n"
|
||||||
|
|
||||||
|
abs : Int → Int
|
||||||
|
abs x = if x < 0 then 0 - x else x
|
||||||
|
|
||||||
|
data Line : U where
|
||||||
|
VL : (x y1 y2 : Int) → Line
|
||||||
|
HL : (y x1 x2 : Int) → Line
|
||||||
|
|
||||||
|
instance Show Line where
|
||||||
|
show (VL x y1 y2) = "VL \{show (x,y1,y2)}"
|
||||||
|
show (HL x y1 y2) = "HL \{show (x,y1,y2)}"
|
||||||
|
|
||||||
|
data Box = B Int Int Int Int
|
||||||
|
|
||||||
|
instance Show Box where
|
||||||
|
show (B l r t b) = "Box \{show (l,r,t,b)}"
|
||||||
|
|
||||||
|
area : Box → Int
|
||||||
|
area (B l r t b) = (abs (l - r) + 1) * (abs (t - b) + 1)
|
||||||
|
|
||||||
|
mkbox : Point → Point → Box
|
||||||
|
mkbox (a,b) (c,d) = B (min a c) (max a c) (min b d) (max b d)
|
||||||
|
|
||||||
|
boxes : List Point → List Box
|
||||||
|
boxes pts = go pts Nil
|
||||||
|
where
|
||||||
|
go2 : Point → List Point → List Box → List Box
|
||||||
|
go2 pt (x :: xs) acc = go2 pt xs (mkbox pt x :: acc)
|
||||||
|
go2 pt _ acc = acc
|
||||||
|
|
||||||
|
go : List Point → List Box → List Box
|
||||||
|
go (pt :: rest) acc = go rest $ go2 pt rest acc
|
||||||
|
go Nil acc = acc
|
||||||
|
|
||||||
|
-- line intersects middle of a box
|
||||||
|
isect : Box → Line → Bool
|
||||||
|
isect (B l r t b) (VL x y1 y2) = x < r && l < x && y1 < b && t < y2
|
||||||
|
isect (B l r t b) (HL y x1 x2) = y < b && t < y && x1 < r && l < x2
|
||||||
|
|
||||||
|
getLines : List Point → List Line
|
||||||
|
getLines points = go points Nil
|
||||||
|
where
|
||||||
|
go : List Point → List Line → List Line
|
||||||
|
go ((a,b) :: rest@((c,d) :: _)) acc =
|
||||||
|
if a == c
|
||||||
|
then let seg = if b < d then VL a b d else VL a d b in go rest (seg :: acc)
|
||||||
|
else if b == d then let seg = if a < c then HL b a c else HL b c a in go rest (seg :: acc)
|
||||||
|
else Nil
|
||||||
|
go _ acc = acc
|
||||||
|
|
||||||
|
-- I'm assuming the winner isn't a single row/column
|
||||||
|
part2 : List (Int × Box) → List Line → Int
|
||||||
|
part2 Nil _ = 0
|
||||||
|
part2 ((size, box) :: rest) lines = if checkRec box then size else part2 rest lines
|
||||||
|
where
|
||||||
|
winds : Box → Line → Bool
|
||||||
|
winds (B l r t b) (VL x y1 y2) =
|
||||||
|
-- pick a point in the middle, the rest is connected because no intersection
|
||||||
|
if t == b then False else r <= x && y1 < t + 1 && t + 1 < y2
|
||||||
|
winds (B l r t b) (HL x y1 y2) = False
|
||||||
|
|
||||||
|
checkRec : Box → Bool
|
||||||
|
checkRec box =
|
||||||
|
let (Nothing) = find (isect box) lines | _ => False in
|
||||||
|
let winding = length' $ filter (winds box) lines in mod winding 2 == 1
|
||||||
|
|
||||||
|
run : String -> IO Unit
|
||||||
|
run fn = do
|
||||||
|
putStrLn fn
|
||||||
|
text <- readFile fn
|
||||||
|
let (pts@(a :: _)) = parse text | _ => putStrLn "empty input"
|
||||||
|
-- printLn pts
|
||||||
|
let sortBoxes = qsort (\ a b => fst a > fst b) $ map (\box => (area box, box)) $ boxes pts
|
||||||
|
let ((p1,_) :: _ ) = sortBoxes | _ => printLn "no boxes"
|
||||||
|
putStrLn $ "part1 \{show p1}"
|
||||||
|
let vl = getLines $ a :: reverse pts
|
||||||
|
putStrLn $ "part2 " ++ show (part2 sortBoxes vl)
|
||||||
|
|
||||||
|
main : IO Unit
|
||||||
|
main = do
|
||||||
|
run "aoc2025/day9/eg.txt"
|
||||||
|
run "aoc2025/day9/input.txt"
|
||||||
8
aoc2025/day9/eg.txt
Normal file
8
aoc2025/day9/eg.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
7,1
|
||||||
|
11,1
|
||||||
|
11,7
|
||||||
|
9,7
|
||||||
|
9,5
|
||||||
|
2,5
|
||||||
|
2,3
|
||||||
|
7,3
|
||||||
Reference in New Issue
Block a user