52 lines
1.3 KiB
Haskell
52 lines
1.3 KiB
Haskell
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
module AoC.Day4 where
|
|
|
|
import Data.Text (Text)
|
|
|
|
import Data.Attoparsec.Text
|
|
import Data.Bits (xor)
|
|
|
|
type Lower = Int
|
|
type Higher = Int
|
|
data Range1D = Range1D Lower Higher
|
|
|
|
included :: Range1D -> Range1D -> Bool
|
|
included (Range1D l1 r1) (Range1D l2 r2) = (l2 <= l1) && (r1 <= r2)
|
|
|
|
eitherIncluded :: Range1D -> Range1D -> Bool
|
|
eitherIncluded range1 range2 =
|
|
(range1 `included` range2) || (range2 `included` range1)
|
|
|
|
parseInput :: Text -> Either String [(Range1D,Range1D)]
|
|
parseInput = parseOnly (parseLine `sepBy` space)
|
|
|
|
parseLine :: Parser (Range1D,Range1D)
|
|
parseLine = do
|
|
l1 <- decimal
|
|
_ <- char '-'
|
|
r1 <- decimal
|
|
_ <- char ','
|
|
l2 <- decimal
|
|
_ <- char '-'
|
|
r2 <- decimal
|
|
pure (Range1D l1 r1,Range1D l2 r2)
|
|
|
|
solveA :: Text -> Either String Int
|
|
solveA txt = do
|
|
lines' <- parseInput txt
|
|
pure $ (length . filter (uncurry eitherIncluded)) lines'
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Part 2
|
|
overlap :: Range1D -> Range1D -> Bool
|
|
overlap (Range1D l1 r1) (Range1D l2 r2) = (r1 >= l2) && (l1 <= r2)
|
|
|
|
eitherOverlap :: Range1D -> Range1D -> Bool
|
|
eitherOverlap range1 range2 = range1 `overlap` range2
|
|
|
|
solveB :: Text -> Either String Int
|
|
solveB txt = do
|
|
lines' <- parseInput txt
|
|
pure $ (length . filter (uncurry eitherOverlap)) lines'
|