{-# LANGUAGE DeriveGeneric #-} | |
module Main where | |
import qualified Data.Char as Char | |
import qualified Data.HashMap.Strict as HM | |
import Data.Hashable | |
import qualified Data.List.Split as S | |
import Data.Maybe (mapMaybe) | |
import GHC.Generics (Generic) | |
main :: IO () | |
main = do | |
contents <- readFile "input.txt" | |
let entries = map parseEntry (S.splitOn "\n\n" contents) | |
print $ length $ filter isEntryValid entries | |
type PassportEntry = HM.HashMap PassportField String | |
data PassportField | |
= BirthYear | |
| IssueYear | |
| ExpirationYear | |
| Height | |
| HairColor | |
| EyeColor | |
| PassportId | |
| CountryId | |
deriving (Eq, Show, Generic) | |
instance Hashable PassportField | |
parseEntry :: String -> PassportEntry | |
parseEntry line = | |
HM.fromList $ | |
mapMaybe parseTag $ | |
S.splitWhen Char.isSpace line | |
parseTag :: String -> Maybe (PassportField, String) | |
parseTag value = | |
case S.splitOn ":" value of | |
["byr", byr] -> | |
Just (BirthYear, byr) | |
["iyr", iyr] -> | |
Just (IssueYear, iyr) | |
["eyr", eyr] -> | |
Just (ExpirationYear, eyr) | |
["hgt", height] -> | |
Just (Height, height) | |
["hcl", color] -> | |
Just (HairColor, color) | |
["ecl", color] -> | |
Just (EyeColor, color) | |
["pid", pid] -> | |
Just (PassportId, pid) | |
["cid", cid] -> | |
Just (CountryId, cid) | |
_ -> | |
Nothing | |
requiredFields :: [PassportField] | |
requiredFields = | |
[ BirthYear, | |
IssueYear, | |
ExpirationYear, | |
Height, | |
HairColor, | |
EyeColor, | |
PassportId | |
] | |
isEntryValid :: PassportEntry -> Bool | |
isEntryValid entry = | |
all (`HM.member` entry) requiredFields |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment