advent-of-code/2020/4/prog.py
2023-08-02 11:39:56 +02:00

82 lines
2.4 KiB
Python

import re
def extract_passports(passports: list):
ret = []
kv_re = re.compile(r'(\w+):(#?\w+)')
for passport in passports:
dic = {}
for key, val in kv_re.findall(passport):
dic[key] = val
ret.append(dic)
return ret
def get_input(sample = False):
with open("sample" if sample else "input", "r") as f:
content = f.read()
passports = content.split("\n\n")
return extract_passports(passports)
def is_passport_valid_1(passport: dict):
fields = {"byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"}
keys = set(passport.keys())
return keys == fields or keys == fields | {"cid"}
between = lambda m1, x, m2: int(m1) <= int(x) and int(x) <= int(m2);
def is_height_valid(height: str):
h_re = re.compile(r'^(\d+)(cm|in)$')
if h_re.match(height) == None: return False
number, measure = h_re.findall(height)[0]
return (measure == "cm" and between(150, number, 193)) or (measure == "in" and between(59, number, 76))
def is_passport_valid_2(passport: dict):
is_four_digits = lambda x: re.match(r'^\d{4}$', x) != None
rules = {"byr": lambda x: is_four_digits(x) and between(1920, x, 2002),
"iyr": lambda x: is_four_digits(x) and between(2010, x, 2020),
"eyr": lambda x: is_four_digits(x) and between(2020, x, 2030),
"hgt": is_height_valid,
"hcl": lambda x: re.match(r'^#[a-f0-9]{6}$', x) != None,
"ecl": lambda x: x in ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"],
"pid": lambda x: re.match(r'^\d{9}$', x) != None,
"cid": lambda x: True}
# try:
# print(passport["hcl"], rules["hcl"](passport["hcl"]))
# except KeyError as e:
# pass
for key, val in passport.items():
if not rules[key](val):
return False
return True
def get_result(passports: list, part = 1):
ret = 0
print(f"{len(passports)=}")
for p in passports:
if (part == 1 and is_passport_valid_1(p)) or (part == 2 and is_passport_valid_2(p) and is_passport_valid_1(p)):
ret += 1
return ret
def main(sample = False, part = 1):
inp = get_input(sample = sample)
res = get_result(inp, part = part)
if sample:
expected = 2 if part == 2 else 0
print(f"{res=}")
print(res == expected)
else:
print(res)
main(sample = False, part = 2)