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 | a > b = (b, a) | otherwise = (a, b) parser :: Parser Intermediate parser = someLines ((,) <$> interval <* char ',' <*> interval) where interval :: Parser Interval interval = makeInterval <$> number <* char '-' <*> number 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 pairFilter :: (a -> b -> Bool) -> [(a, b)] -> [(a, b)] pairFilter f = filter (uncurry f) part1 :: Intermediate -> Int part1 = count (uncurry $ sym contains) part2 :: Intermediate -> Int part2 = count (uncurry overlap) day :: Day day = parsecDay parser (definitive . part1, definitive . part2)