2022-12-04 11:37:59 -05:00
|
|
|
import Data.String
|
|
|
|
import Data.List1
|
|
|
|
import System.File.ReadWrite
|
|
|
|
|
|
|
|
record Range where
|
|
|
|
constructor MkRange
|
|
|
|
start, end : Int
|
|
|
|
|
|
|
|
-- Parse a range from a string like "2-4"
|
|
|
|
parseRange : String -> Maybe Range
|
|
|
|
parseRange str =
|
|
|
|
let components = forget $ Data.String.split (== '-') str
|
|
|
|
in case components of
|
|
|
|
[x, y] => do start <- parseInteger x
|
|
|
|
end <- parseInteger y
|
|
|
|
Just $ MkRange start end
|
|
|
|
_ => Nothing
|
|
|
|
|
|
|
|
-- Return true if the first range contains the second
|
|
|
|
contains : Range -> Range -> Bool
|
|
|
|
contains outer inner = (start outer <= start inner) && (end outer >= end inner)
|
|
|
|
|
2022-12-04 11:53:40 -05:00
|
|
|
-- Returns true if the first range contains part of the second
|
|
|
|
overlaps : Range -> Range -> Bool
|
|
|
|
overlaps outer inner = start outer <= start inner && end outer >= start inner
|
|
|
|
|
2022-12-04 11:37:59 -05:00
|
|
|
record RangePair where
|
|
|
|
constructor MkRangePair
|
|
|
|
first, second : Range
|
|
|
|
|
|
|
|
-- Parse a range pair from a string like "2-4,5-8"
|
|
|
|
parseRangePair : String -> Maybe RangePair
|
|
|
|
parseRangePair str =
|
|
|
|
let components = forget $ Data.String.split (== ',') str
|
|
|
|
in case components of
|
|
|
|
[x, y] => do first <- parseRange x
|
|
|
|
second <- parseRange y
|
|
|
|
Just $ MkRangePair first second
|
|
|
|
_ => Nothing
|
|
|
|
|
|
|
|
-- Returns true if one of the ranges contains the other
|
|
|
|
doesContain : RangePair -> Bool
|
|
|
|
doesContain pair = contains (first pair) (second pair) || contains (second pair) (first pair)
|
|
|
|
|
2022-12-04 11:53:40 -05:00
|
|
|
-- Returns true if one of the ranges overlaps the other
|
|
|
|
doesOverlap : RangePair -> Bool
|
|
|
|
doesOverlap pair = overlaps (first pair) (second pair) || overlaps (second pair) (first pair)
|
|
|
|
|
2022-12-04 11:37:59 -05:00
|
|
|
|
|
|
|
main : IO ()
|
|
|
|
main =
|
|
|
|
do file <- readFile "input"
|
|
|
|
case file of
|
|
|
|
Right content =>
|
|
|
|
let pairs = catMaybes . map parseRangePair . lines $ content
|
|
|
|
containsCount = length . filter doesContain $ pairs
|
2022-12-04 11:53:40 -05:00
|
|
|
overlapsCount = length . filter doesOverlap $ pairs
|
2022-12-04 11:37:59 -05:00
|
|
|
in do putStr "Part 1: "
|
|
|
|
printLn containsCount
|
2022-12-04 11:53:40 -05:00
|
|
|
putStr "Part 2: "
|
|
|
|
printLn overlapsCount
|
2022-12-04 11:37:59 -05:00
|
|
|
Left err => printLn err
|