-
Notifications
You must be signed in to change notification settings - Fork 0
/
run.hs
45 lines (36 loc) · 1.06 KB
/
run.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
36
37
38
39
40
41
42
43
44
45
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE TypeApplications #-}
import Text.Read
type Interval = (Int, Int)
-- Kinda ugly, wanted to try out Text.Read stuff.
parse :: String -> (Interval, Interval)
parse = fst . head . flip readPrec_to_S 0 do
ll <- readPrec @Int
_ <- get
lh <- readPrec @Int
_ <- get
rl <- readPrec @Int
_ <- get
rh <- readPrec @Int
pure ((ll, lh), (rl, rh))
parseAll :: String -> [(Interval, Interval)]
parseAll = map parse . lines
contains :: Interval -> Interval -> Bool
contains (ll, lh) (rl, rh) =
ll <= rl && rh <= lh
overlaps :: Interval -> Interval -> Bool
overlaps (ll, lh) (rl, rh) =
(ll <= rl && rl <= lh)
|| (rl <= ll && ll <= rh)
part1 :: [(Interval, Interval)] -> Int
part1 = length . filter (\(i1, i2) -> i1 `contains` i2 || i2 `contains` i1)
part2 :: [(Interval, Interval)] -> Int
part2 = length . filter (uncurry overlaps)
main :: IO ()
main = main' "input.txt"
main' :: FilePath -> IO ()
main' file = do
input <- parseAll <$> readFile file
print (part1 input)
print (part2 input)