You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
50 lines
1.2 KiB
Haskell
50 lines
1.2 KiB
Haskell
module Day4Lib
|
|
( Range (..),
|
|
parseRange,
|
|
parseRow,
|
|
--
|
|
processInput1,
|
|
processInput2,
|
|
)
|
|
where
|
|
|
|
import Data.List.Split (splitOn)
|
|
|
|
-- import Debug.Trace ()
|
|
|
|
newtype Range = Range (Int, Int) deriving (Show, Eq)
|
|
|
|
parseRange :: String -> Range
|
|
parseRange rs = let [s, e] = map read (splitOn "-" rs) in Range (s, e)
|
|
|
|
parseRow :: String -> [Range]
|
|
parseRow = map parseRange . splitOn ","
|
|
|
|
isInside :: Range -> Range -> Bool
|
|
isInside (Range (s1, e1)) (Range (s2, e2)) = s1 >= s2 && e1 <= e2
|
|
|
|
isOverlapping :: Range -> Range -> Bool
|
|
isOverlapping r1@(Range (s1, e1)) r2@(Range (s2, e2)) =
|
|
Range (s1, s1)
|
|
`isInside` r2
|
|
|| Range (e1, e1)
|
|
`isInside` r2
|
|
|| Range (s2, s2)
|
|
`isInside` r1
|
|
|| Range (e2, e2)
|
|
`isInside` r1
|
|
|
|
-- ####################
|
|
|
|
processInput1 :: String -> Integer
|
|
processInput1 = sum . map processRow1 . lines
|
|
|
|
processRow1 :: String -> Integer
|
|
processRow1 = (\[r1, r2] -> if r1 `isInside` r2 || r2 `isInside` r1 then 1 else 0) . parseRow
|
|
|
|
processInput2 :: String -> Integer
|
|
processInput2 = sum . map processRow2 . lines
|
|
|
|
processRow2 :: String -> Integer
|
|
processRow2 = (\[r1, r2] -> if r1 `isOverlapping` r2 then 1 else 0) . parseRow
|