import std/[options, strutils] import lib/loader type Passport = object byr, iyr, eyr, hgt, hcl, ecl, pid, cid: Option[string] proc addField(p: var Passport, field: string) = let kv = field.split(':') case kv[0] of "byr": p.byr = some(kv[1]) of "iyr": p.iyr = some(kv[1]) of "eyr": p.eyr = some(kv[1]) of "hgt": p.hgt = some(kv[1]) of "hcl": p.hcl = some(kv[1]) of "ecl": p.ecl = some(kv[1]) of "pid": p.pid = some(kv[1]) of "cid": p.cid = some(kv[1]) else: discard var data = @[Passport()] # start with one empty passport for line in loadStrings(4): let pairs = line.splitWhitespace() if pairs.len == 0: data.add(Passport()) else: for pair in pairs: data[^1].addField(pair) proc partOne(data: seq[Passport]): int = for p in data: if ( p.byr.isSome() and p.iyr.isSome() and p.eyr.isSome() and p.hgt.isSome() and p.hcl.isSome() and p.ecl.isSome() and p.pid.isSome() ): inc result func validateYr(year: string; min, max: int): bool = if year.len != 4: return false try: let n = parseInt(year) result = (n >= min and n <= max) except ValueError: result = false func validateHgt(hgt: string): bool = if hgt.len < 3: # need both value and unit return false let value = try: parseInt(hgt[0 .. ^3]) except ValueError: return false let unit = hgt[^2 .. ^1] if unit == "in": return value >= 59 and value <= 76 elif unit == "cm": return value >= 150 and value <= 193 else: return false func validateHcl(hcl: string): bool = if hcl.len != 7 or hcl[0] != '#': return false for c in hcl[2 .. ^1]: if c notin { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }: return false return true func validateEcl(ecl: string): bool = case ecl: of "amb", "blu", "brn", "gry", "grn", "hzl", "oth": return true else: return false func validatePid(pid: string): bool = if pid.len != 9: return false for c in pid: if c notin {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}: return false return true proc partTwo(data: seq[Passport]): int = for p in data: if ( validateYr(p.byr.get(""), 1920, 2002) and validateYr(p.iyr.get(""), 2010, 2020) and validateYr(p.eyr.get(""), 2020, 2030) and validateHgt(p.hgt.get("")) and validateHcl(p.hcl.get("")) and validateEcl(p.ecl.get("")) and validatePid(p.pid.get("")) ): inc result when isMainModule: echo "One: ", partOne(data) echo "Two: ", partTwo(data)