aboutsummaryrefslogtreecommitdiff
path: root/execs/Day02.hs
diff options
context:
space:
mode:
authorAkshay <[email protected]>2020-12-02 14:14:03 +0000
committerAkshay <[email protected]>2020-12-02 14:14:03 +0000
commite80d10cdc7c3ff1e00a698835acbef41eefb945b (patch)
tree2e111bcace1ed4c2ba839e2cbd817e380b7804e0 /execs/Day02.hs
parent7e617b670988e50c43a140a19033162c8695b716 (diff)
clean up day 2 with parsec
Diffstat (limited to 'execs/Day02.hs')
-rw-r--r--execs/Day02.hs50
1 files changed, 28 insertions, 22 deletions
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 @@
1module Main where 1module Main where
2 2
3import Data.Char 3import Data.Char
4import Data.Either
4import Control.Monad 5import Control.Monad
6import Text.ParserCombinators.Parsec
7import Text.Parsec.Char
5 8
6countElem :: (Eq a) => a -> [a] -> Int
7countElem c ls = sum $ map (fromEnum . (== c)) ls 9countElem c ls = sum $ map (fromEnum . (== c)) ls
8 10
9xor :: Bool -> Bool -> Bool 11xor a b = (not a && b) || (a && not b)
10xor True True = False
11xor True False = True
12xor False True = True
13xor False False = False
14 12
15ranges :: [String] -> (Int, Int) 13right (Right a) = a
16ranges r =
17 let p = head r
18 start = read $ takeWhile (/= '-') p
19 end = abs . read $ dropWhile (/= '-') p
20 in (start, end)
21 14
22charac :: [String] -> Char 15data PassProp = PassProp
23charac s = head (s !! 1) 16 { range :: (Int, Int)
17 , c :: Char
18 , pass :: String
19 } deriving (Show)
24 20
25pass :: [String] -> String 21parseProp :: Parser PassProp
26pass = last 22parseProp = do
23 lower <- many1 digit
24 upper <- char '-' >> many1 digit
25 c <- space >> letter
26 password <- string ": " >> many letter
27 return $ PassProp (read lower, read upper) c password
27 28
28doCheck1 :: ((Int, Int), Char , String) -> Bool 29doCheck1 :: PassProp -> Bool
29doCheck1 ((lower, upper), c, pass) = count >= lower && count <= upper 30doCheck1 PassProp { range = (lower, upper), c = c, pass = pass} =
30 where count = countElem c pass 31 count >= lower && count <= upper
32 where count = countElem c pass
31 33
32doCheck2 :: ((Int, Int), Char , String) -> Bool 34doCheck2 :: PassProp -> Bool
33doCheck2 ((lower, upper), c, pass) = (pass !! (lower - 1) == c) `xor` (pass !! (upper - 1) == c) 35doCheck2 PassProp { range = (lower, upper), c = c, pass = pass} =
36 (pass !! (lower - 1) == c) `xor` (pass !! (upper - 1) == c)
37
38parseLine :: Parser a -> String -> a
39parseLine parser line = right $ parse parser "input" line
34 40
35main :: IO () 41main :: IO ()
36main = do 42main = do
37 n <- map (fromEnum . doCheck2 . (\w -> (ranges w, charac w, pass w)) . words) . lines <$> readFile "input/02" 43 n <- map (fromEnum . doCheck2 . parseLine parseProp) . lines <$> readFile "input/02"
38 print $ sum n 44 print $ sum n
39 45