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 --- aoc.cabal | 2 +- execs/Day02.hs | 50 ++++++++++++++++++++++++++++---------------------- shell.nix | 2 -- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/aoc.cabal b/aoc.cabal index c61a9a4..6dbd463 100644 --- a/aoc.cabal +++ b/aoc.cabal @@ -24,6 +24,6 @@ executable Day01 executable Day02 main-is: Day02.hs - build-depends: base + build-depends: base, parsec default-language: Haskell2010 hs-source-dirs: 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 diff --git a/shell.nix b/shell.nix index f1d55b5..ba7d852 100644 --- a/shell.nix +++ b/shell.nix @@ -19,9 +19,7 @@ let haskellDeps = ps: with ps; [ base - lens parsec - mtl ]; ghc = haskellPackages.ghcWithPackages haskellDeps; -- cgit v1.2.3