-
Notifications
You must be signed in to change notification settings - Fork 0
/
4a.hs
65 lines (51 loc) · 1.32 KB
/
4a.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
64
65
{-# LANGUAGE OverloadedStrings #-}
import Data.Either
import Data.List
import Text.ParserCombinators.Parsec
import Prelude
main = do
input <- getContents
putStr $ show $ fn input
birthyearP = parserGen "byr" True
issueYearP = parserGen "iyr" True
expirationYearP = parserGen "eyr" True
heightP = parserGen "hgt" True
hairColorP = parserGen "hcl" True
eyeColorP = parserGen "ecl" True
passportIdP = parserGen "pid" True
countryIdP = parserGen "cid" False
parserGen :: String -> Bool -> GenParser Char Int Int
parserGen x required = do
try $ string x
char ':'
optional $ char '#'
many1 alphaNum
choice [space, newline]
if required then return 1 else return 0
singlePassportParser :: GenParser Char Int ()
singlePassportParser = do
valids <-
many1 $
choice
[ birthyearP,
issueYearP,
expirationYearP,
heightP,
hairColorP,
eyeColorP,
passportIdP,
countryIdP
]
state <- getState
setState (if sum valids >= 7 then state + 1 else state)
return ()
passportParser :: GenParser Char Int Int
passportParser = do
many1 $ choice [singlePassportParser, skipMany1 newline]
eof
state <- getState
return state
fn :: String -> String
fn x = case runParser passportParser 0 "Err" x of
Left err -> show err
Right x -> show x