2023-08-30 10:02:11 +02:00
|
|
|
module Days.D04 where
|
|
|
|
|
|
|
|
|
|
import Text.Megaparsec.Char as C (char)
|
|
|
|
|
|
|
|
|
|
import Common
|
|
|
|
|
import Parse (Parser, number, parsecDay, someLines)
|
|
|
|
|
import Util (count)
|
|
|
|
|
|
|
|
|
|
type Interval = (Int, Int)
|
|
|
|
|
type Intermediate = [(Interval, Interval)]
|
|
|
|
|
|
|
|
|
|
makeInterval :: (Ord a) => a -> a -> (a, a)
|
|
|
|
|
makeInterval a b
|
2023-08-30 13:39:18 +02:00
|
|
|
| a > b = (b, a)
|
|
|
|
|
| otherwise = (a, b)
|
2023-08-30 10:02:11 +02:00
|
|
|
|
|
|
|
|
parser :: Parser Intermediate
|
|
|
|
|
parser = someLines ((,) <$> interval <* char ',' <*> interval)
|
2023-08-30 13:39:18 +02:00
|
|
|
where
|
|
|
|
|
interval :: Parser Interval
|
|
|
|
|
interval = makeInterval <$> number <* char '-' <*> number
|
2023-08-30 10:02:11 +02:00
|
|
|
|
|
|
|
|
contains :: Interval -> Interval -> Bool
|
|
|
|
|
contains (a, b) (c, d) = a <= c && b >= d
|
|
|
|
|
|
|
|
|
|
overlap :: Interval -> Interval -> Bool
|
|
|
|
|
overlap (a, b) (c, d) = not (b < c || a > d)
|
|
|
|
|
|
|
|
|
|
sym :: (a -> a -> Bool) -> (a -> a -> Bool)
|
|
|
|
|
sym f a b = f a b || f b a
|
|
|
|
|
|
|
|
|
|
part1 :: Intermediate -> Int
|
|
|
|
|
part1 = count (uncurry $ sym contains)
|
|
|
|
|
|
|
|
|
|
part2 :: Intermediate -> Int
|
|
|
|
|
part2 = count (uncurry overlap)
|
|
|
|
|
|
|
|
|
|
day :: Day
|
|
|
|
|
day = parsecDay parser (definitive . part1, definitive . part2)
|