import re re_hgt = re.compile(r"(?P\d+)(?Pcm|in)") re_hcl = re.compile(r"#[\da-f]{6}") re_pid = re.compile(r"^\d{9}$") def parse(data): rec = {} for line in data.split("\n"): if not line: yield rec rec = {} continue pairs = line.split(" ") for pair in pairs: k, v = pair.split(":", 1) rec[k] = v def load(filename): with open(filename, "r", encoding="utf-8") as f: s = f.read() return parse(s) def is_valid_1(rec): required_fields = set(("byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid")) fields = set(rec.keys()) return not (required_fields - fields) def is_valid_2(rec): if not is_valid_1(rec): return False if not 1920 <= int(rec["byr"]) <= 2002: return False if not 2010 <= int(rec["iyr"]) <= 2020: return False if not 2020 <= int(rec["eyr"]) <= 2030: return False m = re_hgt.match(rec["hgt"]) if not m: return False if m.group("type") == "cm": if not 150 <= int(m.group("no")) <= 193: return False elif m.group("type") == "in": if not 59 <= int(m.group("no")) <= 76: return False m = re_hcl.match(rec["hcl"]) if not m: return False if rec["ecl"] not in ("amb", "blu", "brn", "gry", "grn", "hzl", "oth"): return False if not re_pid.match(rec["pid"]): return False return True if __name__ == "__main__": data = load("data.txt") n_valid_1 = n_valid_2 = 0 for x in data: if is_valid_1(x): n_valid_1 += 1 if is_valid_2(x): n_valid_2 += 1 print(f"Task 1: There are {n_valid_1} valid passports.") print(f"Task 2: There are {n_valid_2} valid passports.")