-
Notifications
You must be signed in to change notification settings - Fork 0
/
day3.hs
35 lines (28 loc) · 1.1 KB
/
day3.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import Data.List
import Data.Maybe
import Data.Map (Map, (!))
import qualified Data.Map as Map
type Claim = (Int, Int, Int, Int, Int)
addClaim :: Map (Int, Int) Int -> Claim -> Map (Int, Int) Int
addClaim areas = Map.unionWith (+) areas . Map.fromList . map (\s -> (s, 1)) . getArea
getArea :: Claim -> [(Int, Int)]
getArea (_, left, top, width, height) = do
x <- [left .. left + width - 1]
y <- [top .. top + height - 1]
return (x, y)
overlaps :: Map (Int, Int) Int -> Claim -> Bool
overlaps areas = any (\s -> areas ! s > 1) . getArea
parse :: [String] -> Claim
parse ['#':id_, "@", offsets, size] =
let [(left, ',':top_)] = reads offsets
[(top, ":")] = reads top_
[(width, 'x':height_)] = reads size
height = read height_
in (read id_, left, top, width, height)
part1 :: String -> Int
part1 = Map.size . Map.filter (>1) . foldl addClaim Map.empty . map (parse . words) . lines
part2 :: String -> Int
part2 input = id
where claims = map (parse . words) $ lines input
areas = foldl addClaim Map.empty claims
(id, _, _, _, _) = fromJust $ find (not . overlaps areas) claims