aboutsummaryrefslogtreecommitdiff
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
parent7e617b670988e50c43a140a19033162c8695b716 (diff)
clean up day 2 with parsec
-rw-r--r--aoc.cabal2
-rw-r--r--execs/Day02.hs50
-rw-r--r--shell.nix2
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
24 24
25executable Day02 25executable Day02
26 main-is: Day02.hs 26 main-is: Day02.hs
27 build-depends: base 27 build-depends: base, parsec
28 default-language: Haskell2010 28 default-language: Haskell2010
29 hs-source-dirs: execs 29 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 @@
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
diff --git a/shell.nix b/shell.nix
index f1d55b5..ba7d852 100644
--- a/shell.nix
+++ b/shell.nix
@@ -19,9 +19,7 @@ let
19 19
20 haskellDeps = ps: with ps; [ 20 haskellDeps = ps: with ps; [
21 base 21 base
22 lens
23 parsec 22 parsec
24 mtl
25 ]; 23 ];
26 24
27 ghc = haskellPackages.ghcWithPackages haskellDeps; 25 ghc = haskellPackages.ghcWithPackages haskellDeps;