module Main where import System.Environment (getArgs) import Text.Parsec (parse, many1, char, sepBy, endBy) import Text.Parsec.Char (endOfLine) import Text.ParserCombinators.Parsec (GenParser) import Text.ParserCombinators.Parsec.Number (decimal) type Report = [Level] type Level = Int reports :: GenParser Char st [Report] reports = endBy report endOfLine report :: GenParser Char st Report report = sepBy level (many1 (char ' ')) level :: GenParser Char st Level level = decimal pairUp :: [a] -> [(a, a)] pairUp (a:b:tl) = (a, b) : pairUp (b:tl) pairUp _ = [] allIncOrDec :: Report -> Bool allIncOrDec (a:b:tl) | a /= b = all (uncurry (if a < b then (<) else (>))) $ pairUp $ b:tl | otherwise = False allIncOrDec _ = True notTooDifferent :: Report -> Bool notTooDifferent (a:b:tl) = let dif = abs (a - b) in (1 <= dif) && (dif <= 3) && notTooDifferent (b:tl) notTooDifferent _ = True part1 :: [Report] -> Int part1 = length . filter allIncOrDec . filter notTooDifferent main :: IO () main = do args <- getArgs (fp:_) <- return args content <- readFile fp case parse reports fp content of Left e -> putStrLn ("Input file is incorrectly formatted : " ++ show e) Right r -> do putStrLn ("Solution (Part 1) : " ++ show (part1 r)) -- putStrLn ("Solution (Part 2) : " ++ show (part2 r))