diff options
author | Julien Dessaux | 2023-03-08 23:21:52 +0100 |
---|---|---|
committer | Julien Dessaux | 2023-03-08 23:21:52 +0100 |
commit | 662b77da67600ca088890eda21ece136f693e4a0 (patch) | |
tree | 63a1d54682fb9cfa15c82d05002d56beb7b2d369 /2020/02-Password_Philosophy/first.hs | |
parent | 2020-01 part 2 in haskell (diff) | |
download | advent-of-code-662b77da67600ca088890eda21ece136f693e4a0.tar.gz advent-of-code-662b77da67600ca088890eda21ece136f693e4a0.tar.bz2 advent-of-code-662b77da67600ca088890eda21ece136f693e4a0.zip |
2020-02 in haskell
Diffstat (limited to '')
-rw-r--r-- | 2020/02-Password_Philosophy/first.hs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/2020/02-Password_Philosophy/first.hs b/2020/02-Password_Philosophy/first.hs new file mode 100644 index 0000000..85c092e --- /dev/null +++ b/2020/02-Password_Philosophy/first.hs @@ -0,0 +1,59 @@ +-- requires cabal install --lib megaparsec +module Main (main) where + +import Control.Monad (void, when) +import Data.Void +import Text.Megaparsec +import Text.Megaparsec.Char +import System.Exit (die) + +exampleExpectedOutput = 2 + +data Rule = Rule { lower :: Int + , higher :: Int + , elt :: Char + , pass :: String + } deriving (Show) + +type Parser = Parsec Void String + +parseRule :: Parser Rule +parseRule = do + l <- try (some digitChar) + void (char '-') + h <- try (some digitChar) + void (char ' ') + e <- anySingle + void (string ": ") + pass <- (many letterChar) + void (char '\n') + return Rule { lower = read l, higher = read h, elt = e, pass = pass } + +parseRules :: Parser [Rule] +parseRules = do + rules <- many parseRule + eof + return rules + +parseInput :: String -> IO [Rule] +parseInput filename = do + input <- readFile filename + case runParser parseRules filename input of + Left bundle -> die $ errorBundlePretty bundle + Right rules -> return rules + +validateRule :: Rule -> Int +validateRule Rule{lower=l, higher=h, elt=e, pass=pass} = if (n >= l && n <= h) then 1 else 0 + where + n = length $ filter (== e) pass + +compute :: [Rule] -> Int +compute = sum . map validateRule + +main :: IO () +main = do + example <- parseInput "example" + let exampleOutput = compute example + when (exampleOutput /= exampleExpectedOutput) (die $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput) + input <- parseInput "input" + print $ compute input |