From 662b77da67600ca088890eda21ece136f693e4a0 Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Wed, 8 Mar 2023 23:21:52 +0100 Subject: 2020-02 in haskell --- 2020/02-Password_Philosophy/second.hs | 60 +++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 2020/02-Password_Philosophy/second.hs (limited to '2020/02-Password_Philosophy/second.hs') diff --git a/2020/02-Password_Philosophy/second.hs b/2020/02-Password_Philosophy/second.hs new file mode 100644 index 0000000..973a818 --- /dev/null +++ b/2020/02-Password_Philosophy/second.hs @@ -0,0 +1,60 @@ +-- 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 = 1 + +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) - 1, higher = (read h) - 1, 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 (a /= b) then 1 else 0 + where + a = e == pass !! l + b = e == pass !! h + +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 -- cgit v1.2.3