Day 4: Passport Processing - Part 2
The automatic passport scanners are slow because they're having trouble detecting which passports have all required fields. The expected fields are as follows:
byr
(Birth Year) - four digits; at least 1920 and at most 2002.iyr
(Issue Year) - four digits; at least 2010 and at most 2020.eyr
(Expiration Year) - four digits; at least 2020 and at most 2030.hgt
(Height) - a number followed by either cm or in:- If
cm
, the number must be at least 150 and at most 193. - If
in
, the number must be at least 59 and at most 76.
- If
hcl
(Hair Color) - a#
followed by exactly six characters0-9
ora-f
.ecl
(Eye Color) - exactly one of:amb blu brn gry grn hzl oth
.pid
(Passport ID) - a nine-digit number, including leading zeroes.cid
(Country ID) - ignored, missing or not.
Your input example:
ecl:gry pid:860033327 eyr:2020 hcl:#fffffd
byr:1937 iyr:2017 cid:147 hgt:183cm
iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884
hcl:#cfa07d byr:1929
hcl:#ae17e1 iyr:2013
eyr:2024
ecl:brn pid:760753108 byr:1931
hgt:179cm
hcl:#cfa07d eyr:2025 pid:166559648
iyr:2011 ecl:brn hgt:59in
You ignore the cid
field because your passport does not have it to begin with. Your job is to count the passports where all required fields are both present and valid according to the above rules.
In your batch file, how many passports are valid?
The Rules Design Pattern from here came in handy. I created a base interface:
interface Rule {
isValid(passport: Passport): boolean;
}
and created several rules off of that. I also created an And
rule for composition:
class AndRule implements Rule {
constructor(private readonly rules: Rule[]) {}
isValid(passport: Passport) {
return this.rules.every((r) => r.isValid(passport));
}
}
function and(...rules: Rule[]): Rule {
return new AndRule(rules);
}
This allowed me to create all the rules like such:
and(
new BirthYearRule(),
new IssueYearRule(),
new ExpirationYearRule(),
new HeightRule(),
new HairColorRule(),
new EyeColorRule(),
new PassportIdRule()
);