-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday2.hs
63 lines (53 loc) · 1.67 KB
/
day2.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import System.IO
( IOMode(ReadMode), hClose, hGetContents, openFile )
import Control.Monad (void)
import Text.Parsec (ParseError, parse)
import Text.Parsec.String (Parser)
import Text.Parsec.Char (oneOf, char, digit, anyChar)
import Text.Parsec.Combinator (many1)
import Control.Applicative (many)
import Data.Char (isLetter, isDigit)
import Data.Either (rights)
data Policy = Policy
{ pIx1 :: Int
, pIx2 :: Int
, pChar :: Char
, pPass :: String
}
deriving (Show, Eq)
policyParser :: Parser Policy
policyParser = do
n <- many1 digit
void $ char '-'
m <- many1 digit
void $ char ' '
c <- anyChar
void $ char ':'
void $ char ' '
rest <- many anyChar
return (Policy (read n) (read m) c rest)
countLetters :: String -> Char -> Int
countLetters str c = length $ filter (== c) str
validPolicy1 :: Policy -> Bool
validPolicy1 (Policy pIx1 pIx2 pChar pPass) = n >= pIx1 && n <= pIx2
where
n = countLetters pPass pChar
solve1 :: [Policy] -> Int
solve1 ps = length [p | p <- ps, validPolicy1 p]
substring :: Int -> Int -> String -> String
substring start end text = take (end - start) (drop start text)
validPolicy2 :: Policy -> Bool
validPolicy2 (Policy pIx1 pIx2 pChar pPass) = (pPass !! (pIx1-1) == pChar) /= (pPass !! (pIx2-1) == pChar)
solve2 :: [Policy] -> Int
solve2 ps = length [p | p <- ps, validPolicy2 p]
main :: IO ()
main = do
let list = []
handle <- openFile "input2.txt" ReadMode
contents <- hGetContents handle
let policies = rights (map (parse policyParser "") (lines contents))
print (solve1 policies)
print (solve2 policies)
hClose handle
-- 483
-- 482