day4: simplify part2

This commit is contained in:
Johannes Loher 2020-12-04 12:32:58 +01:00
parent d63da28b74
commit 8c2798e26b

View file

@ -17,31 +17,6 @@ auto parsePassports(string input)
}).assocArray);
}
enum Field : string
{
birthYear = "byr",
issueYear = "iyr",
expirationYear = "eyr",
height = "hgt",
hairColor = "hcl",
eyeColor = "ecl",
passportID = "pid",
countryID = "cid",
}
bool isValidYear(int min, int max)(string yr)
{
if (yr.length != 4 || yr.canFind!(not!isDigit))
return false;
auto year = yr.to!int;
return year >= min && year <= max;
}
alias isValidBirthYear = isValidYear!(1920, 2002);
alias isValidIssueYear = isValidYear!(2010, 2020);
alias isValidExpirationYear = isValidYear!(2020, 2030);
bool isValidHeight(string hgt)
{
auto match = hgt.matchFirst(r"^(\d+)(cm|in)$");
@ -61,36 +36,24 @@ bool isValidHeight(string hgt)
}
}
bool isValidHairColor(string hcl)
{
return hcl.matchFirst(r"^#[0-9a-f]{6}$").to!bool;
}
bool isValidEyeColor(string ecl)
{
return ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"].canFind(ecl);
}
bool isValidPassportID(string pid)
{
return pid.matchFirst(r"^\d{9}$").to!bool;
}
enum requiredFields = [
Field.birthYear, Field.issueYear, Field.expirationYear, Field.height,
Field.hairColor, Field.eyeColor, Field.passportID
];
alias isBetween = (x, min, max) => x >= min && x <= max;
bool isValidPassport(Passport passport)
{
return requiredFields.all!(field => field in passport)
&& isValidBirthYear(passport[Field.birthYear])
&& isValidIssueYear(passport[Field.issueYear])
&& isValidExpirationYear(passport[Field.expirationYear])
&& isValidHeight(passport[Field.height])
&& isValidHairColor(passport[Field.hairColor])
&& isValidEyeColor(passport[Field.eyeColor])
&& isValidPassportID(passport[Field.passportID]);
// dfmt off
auto validators = [
"byr" : s => s.length == 4 && s.all!isDigit && s.to!int.isBetween(1920, 2002),
"iyr" : s => s.length == 4 && s.all!isDigit && s.to!int.isBetween(2010, 2020),
"eyr" : s => s.length == 4 && s.all!isDigit && s.to!int.isBetween(2020, 2030),
"hgt" : &isValidHeight,
"hcl" : s => s.matchFirst(r"^#[0-9a-f]{6}$").to!bool,
"ecl" : s => [ "amb", "blu", "brn", "gry", "grn", "hzl", "oth" ].canFind(s),
"pid" : s => s.matchFirst(r"^\d{9}$").to!bool
];
// dfmt on
return validators.byKeyValue.all!(validator => validator.key in passport
&& validator.value()(passport[validator.key]));
}
auto countValidPassports(R)(R r) if (isInputRange!R && is(ElementType!R == Passport))