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) 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) main : IO () main = do file <- readFile "input" case file of Right content => let pairs = catMaybes . map parseRangePair . lines $ content containsCount = length . filter doesContain $ pairs in do putStr "Part 1: " printLn containsCount Left err => printLn err