From e80d10cdc7c3ff1e00a698835acbef41eefb945b Mon Sep 17 00:00:00 2001 From: Akshay Date: Wed, 2 Dec 2020 19:44:03 +0530 Subject: clean up day 2 with parsec --- execs/Day02.hs | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'execs') diff --git a/execs/Day02.hs b/execs/Day02.hs index bcb0896..87c90ec 100644 --- a/execs/Day02.hs +++ b/execs/Day02.hs @@ -1,39 +1,45 @@ module Main where import Data.Char +import Data.Either import Control.Monad +import Text.ParserCombinators.Parsec +import Text.Parsec.Char -countElem :: (Eq a) => a -> [a] -> Int countElem c ls = sum $ map (fromEnum . (== c)) ls -xor :: Bool -> Bool -> Bool -xor True True = False -xor True False = True -xor False True = True -xor False False = False +xor a b = (not a && b) || (a && not b) -ranges :: [String] -> (Int, Int) -ranges r = - let p = head r - start = read $ takeWhile (/= '-') p - end = abs . read $ dropWhile (/= '-') p - in (start, end) +right (Right a) = a -charac :: [String] -> Char -charac s = head (s !! 1) +data PassProp = PassProp + { range :: (Int, Int) + , c :: Char + , pass :: String + } deriving (Show) -pass :: [String] -> String -pass = last +parseProp :: Parser PassProp +parseProp = do + lower <- many1 digit + upper <- char '-' >> many1 digit + c <- space >> letter + password <- string ": " >> many letter + return $ PassProp (read lower, read upper) c password -doCheck1 :: ((Int, Int), Char , String) -> Bool -doCheck1 ((lower, upper), c, pass) = count >= lower && count <= upper - where count = countElem c pass +doCheck1 :: PassProp -> Bool +doCheck1 PassProp { range = (lower, upper), c = c, pass = pass} = + count >= lower && count <= upper + where count = countElem c pass -doCheck2 :: ((Int, Int), Char , String) -> Bool -doCheck2 ((lower, upper), c, pass) = (pass !! (lower - 1) == c) `xor` (pass !! (upper - 1) == c) +doCheck2 :: PassProp -> Bool +doCheck2 PassProp { range = (lower, upper), c = c, pass = pass} = + (pass !! (lower - 1) == c) `xor` (pass !! (upper - 1) == c) + +parseLine :: Parser a -> String -> a +parseLine parser line = right $ parse parser "input" line main :: IO () main = do - n <- map (fromEnum . doCheck2 . (\w -> (ranges w, charac w, pass w)) . words) . lines <$> readFile "input/02" + n <- map (fromEnum . doCheck2 . parseLine parseProp) . lines <$> readFile "input/02" print $ sum n -- cgit v1.2.3