adventofcode/2020/04/main.py
2022-12-02 09:41:56 +01:00

81 lines
1.5 KiB
Python

import re
re_hgt = re.compile(r"(?P<no>\d+)(?P<type>cm|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.")