#!/usr/bin/env runghc

  -- byr (Birth Year)
  -- iyr (Issue Year)
  -- eyr (Expiration Year)
  -- hgt (Height)
  -- hcl (Hair Color)
  -- ecl (Eye Color)
  -- pid (Passport ID)
  -- cid (Country ID)

import Data.Char
import Data.Map.Strict (fromList, member)


isValidEntry ("byr", byr)
  | byr >= "1920" && byr <= "2002" = True
  | otherwise = False
isValidEntry ("iyr", iyr)
  | iyr >= "2010" && iyr <= "2020" = True
  | otherwise = False
isValidEntry ("eyr", eyr)
  | eyr >= "2020" && eyr <= "2030" = True
  | otherwise = False
isValidEntry ("hgt", hgt@(a:b:c:"cm")) = hgt >= "150cm" && hgt <= "193cm"
isValidEntry ("hgt", hgt@(a:b:"in")) = hgt >= "59in" && hgt <= "76in"
isValidEntry ("hcl", '#':hcl) = length hcl == 6 && all isHexDigit hcl
isValidEntry ("ecl", "amb") = True
isValidEntry ("ecl", "blu") = True
isValidEntry ("ecl", "brn") = True
isValidEntry ("ecl", "gry") = True
isValidEntry ("ecl", "grn") = True
isValidEntry ("ecl", "hzl") = True
isValidEntry ("ecl", "oth") = True
isValidEntry ("pid", pid) = length pid == 9 && all isDigit pid
isValidEntry ("cid", _) = True -- ignored
isValidEntry _ = False

toEntry = fmap tail . break (==':') 

main = interact (solve . getMaps)

solve = show . length . filter isValidDocument

isValidDocument document =
  member "byr" document &&
  member "iyr" document &&
  member "eyr" document &&
  member "hgt" document &&
  member "hcl" document &&
  member "ecl" document &&
  member "pid" document

getMaps = map (fromList . filter isValidEntry . map toEntry . words) . joinLines . lines

joinLines = foldl parse [""]
  where 
    parse [""] l = [l]
    parse [a] "" = ["", a]
    parse [a] l = [l ++ " " ++ a]
    parse (a:as) l = parse [a] l ++ as