import re input_file = "input.txt" height_re = re.compile(r'^([0-9]+)(in|cm)$') passport_id_re = re.compile(r'^[0-9]{9}$') color_re = re.compile(r'^#[0-9a-f]{6}$') def check_limits(to_test, min_valid, max_valid): return False if (to_test < min_valid or to_test > max_valid) else True def validate_passport(record): for field in record: if field[0] == "byr": if not check_limits(int(field[1]), 1920, 2002): return False elif field[0] == "iyr": if not check_limits(int(field[1]), 2010, 2020): return False elif field[0] == "eyr": if not check_limits(int(field[1]), 2020, 2030): return False elif field[0] == "hgt": regex_match = height_re.match(field[1]) if not regex_match: return False if regex_match.groups()[1] == "cm" and not check_limits(int(regex_match.groups()[0]), 150, 193): return False elif regex_match.groups()[1] == "in" and not check_limits(int(regex_match.groups()[0]), 59, 76): return False elif field[0] == "hcl": regex_match = color_re.match(field[1]) if not regex_match: return False elif field[0] == "ecl": if field[1] not in ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"]: return False elif field[0] == "pid": regex_match = passport_id_re.match(field[1]) if not regex_match: return False return True records = [[]] valid_passports = 0 with open(input_file) as passports: line = passports.readline() current_index = 0 while line: if line == "\n": records.append([]) current_index += 1 line = passports.readline() continue # rstrip() strips the string from end of line characters et alia. for raw_entry in line.rstrip().split(" "): # Split the different fields, then split them in (key,value) tuples records[current_index].append(tuple(raw_entry.split(":"))) line = passports.readline() for record in records: if len(record) == 8: if validate_passport(record): valid_passports += 1 if len(record) == 7: is_north_pole_credential = True for field in record: if field[0] == "cid": is_north_pole_credential = False break if is_north_pole_credential and validate_passport(record): valid_passports += 1 print(f"There are {valid_passports} valid passports out of {len(records)}")