AoC 2020 D4: Passport Processing

Python | Problem statement | Source code | Tags: String manipulation

← Previous Back to AoC Index Next →

Part 1

For each passport, we first collect the fields as (key, value) pairs in a dictionary:

parts = entry.replace("\n", " ").split()
fields: dict[str, str] = {}
for part in parts:
subparts = part.split(":", 1)
fields[subparts[0]] = subparts[1]
python

Then we check if all required fields are present:

if all(k in fields for k in required.keys()):
count += 1
python

(The required dictionary is defined for part 2.)

Part 2

When I first did part 1, required was just a set of field names. For part 2, I changed it to a dictionary mapping field names to validation functions. Different fields have different validation rules, so this makes it easy to organize them:

required: dict[str, Callable[[str], bool]] = {
"byr": lambda x: 1920 <= int(x) <= 2002,
"iyr": lambda x: 2010 <= int(x) <= 2020,
"eyr": lambda x: 2020 <= int(x) <= 2030,
"hgt": lambda x: (x.endswith("cm") and 150 <= int(x[:-2]) <= 193)
or (x.endswith("in") and 59 <= int(x[:-2]) <= 76),
"hcl": lambda x: re.match(r"^#[0-9a-f]{6}$", x) is not None,
"ecl": lambda x: x in ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"],
"pid": lambda x: re.match(r"^[0-9]{9}$", x) is not None,
}
python

The validation rules include range checks, string pattern checks, and a mix of both (for hgt).

The problem is vague about what to do with duplicate fields, so for duplicate fields, I immediately invalidate the passport, and only validate passports with unique fields. This is straightforward in Python with for...else:

for part in parts:
subparts = part.split(":", 1)
if subparts[0] in fields:
break
fields[subparts[0]] = subparts[1]
else:
if all(k in fields and required[k](fields[k]) for k in required.keys()):
count += 1
python

← Previous Back to AoC Index Next →