-
Notifications
You must be signed in to change notification settings - Fork 0
/
day05.hs
32 lines (24 loc) · 995 Bytes
/
day05.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
import Data.List
import Data.List.Split
import Data.Set (Set)
import qualified Data.Set as S
type Point = (Int, Int)
data Line = Line Point Point deriving (Eq, Show)
main :: IO ()
main = interact (unlines . sequence [part1, part2] . map parse . lines)
part1, part2 :: [Line] -> String
part1 = ("Part 1: " ++) . show . S.size . overlap . map points . filter isPerpendicular
part2 = ("Part 2: " ++) . show . S.size . overlap . map points
overlap :: Ord a => [Set a] -> Set a
overlap lines = S.unions [S.intersection p1 p2 | (p1 : ps) <- tails lines, p2 <- ps]
points :: Line -> Set Point
points (Line (x1, y1) (x2, y2)) = S.fromList $ zip (range x1 x2) (range y1 y2)
where
range a b = [a, a + signum (b - a) .. b]
isPerpendicular :: Line -> Bool
isPerpendicular (Line (x1, y1) (x2, y2)) = x1 == x2 || y1 == y2
parse :: String -> Line
parse = toLine . map (toPoint . map read . splitOn ",") . splitOn " -> "
where
toPoint [x, y] = (x, y)
toLine [start, end] = Line start end