summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcos <cos>2020-12-05 00:34:36 +0100
committercos <cos>2020-12-05 00:34:42 +0100
commit6dab82d7ebd2edea2a1220cfbaff977528c6aaca (patch)
tree7212a2c32a0b7584cefa8f40144e5ab413901c05
parent1630c01b93513a650c8cb550bcad2da9a6d9d4fb (diff)
downloadadventofcode-6dab82d7ebd2edea2a1220cfbaff977528c6aaca.zip
Refactor day04 to make full use of regex
-rw-r--r--2020/rust/day04/src/main.rs95
1 files changed, 25 insertions, 70 deletions
diff --git a/2020/rust/day04/src/main.rs b/2020/rust/day04/src/main.rs
index 34ae9bc..0d4c901 100644
--- a/2020/rust/day04/src/main.rs
+++ b/2020/rust/day04/src/main.rs
@@ -50,81 +50,36 @@ fn part1(input: &[Passport]) -> usize {
fn part2(input: &[Passport]) -> Result<usize> {
let mut valid_count = 0;
- let hgt_re = Regex::new(r"^(?P<value>\d+)(?P<unit>cm|in)$")?;
- let hcl_re = Regex::new(r"^#[0-9a-f]{6}$")?;
- let ecl_re = Regex::new(r"^(amb|blu|brn|gry|grn|hzl|oth)$")?;
- let pid_re = Regex::new(r"^\d{9}$")?;
+ let mut re: HashMap<String, Regex> = HashMap::new();
+
+ // byr (Birth Year) - four digits; at least 1920 and at most 2002.
+ re.insert(String::from("byr"), Regex::new(r"^(19[2-9][0-9])|(200[0-2])$")?);
+ // iyr (Issue Year) - four digits; at least 2010 and at most 2020.
+ re.insert(String::from("iyr"), Regex::new(r"^20(1[0-9])|(20)$")?);
+ // eyr (Expiration Year) - four digits; at least 2020 and at most 2030.
+ re.insert(String::from("eyr"), Regex::new(r"^20(2[0-9])|(30)$")?);
+ // 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.
+ re.insert(String::from("hgt"),
+ Regex::new(r"^1(([5-8][0-9])|(9[0-3]))cm|((59)|(6[0-9])|(7[0-6]))in$")?);
+ // hcl (Hair Color) - a # followed by exactly six characters 0-9 or a-f.
+ re.insert(String::from("hcl"), Regex::new(r"^#[0-9a-f]{6}$")?);
+ // ecl (Eye Color) - exactly one of: amb blu brn gry grn hzl oth.
+ re.insert(String::from("ecl"), Regex::new(r"^(amb|blu|brn|gry|grn|hzl|oth)$")?);
+ // pid (Passport ID) - a nine-digit number, including leading zeroes.
+ re.insert(String::from("pid"), Regex::new(r"^\d{9}$")?);
+ // cid (Country ID) - ignored, missing or not.
'validate: for passport in input {
- // byr (Birth Year) - four digits; at least 1920 and at most 2002.
- match passport.get("byr") {
- Some(byr) => match byr.parse() {
- Ok(1920..=2002) => {},
- _ => continue 'validate,
- }
- _ => continue 'validate,
- }
- // iyr (Issue Year) - four digits; at least 2010 and at most 2020.
- match passport.get("iyr") {
- Some(iyr) => match iyr.parse() {
- Ok(2010..=2020) => {},
- _ => continue 'validate,
- }
- _ => continue 'validate,
- }
- // eyr (Expiration Year) - four digits; at least 2020 and at most 2030.
- match passport.get("eyr") {
- Some(eyr) => match eyr.parse() {
- Ok(2020..=2030) => {},
+ for key in &["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"] {
+ match (passport.get(*key), re.get(*key)) {
+ (Some(val), Some(re)) => if ! re.is_match(val) {
+ continue 'validate;
+ },
_ => continue 'validate,
}
- _ => continue 'validate,
- }
- // 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.
- match passport.get("hgt") {
- Some(hgt) => match hgt_re.captures(hgt) {
- Some(caps) => match &caps.name("unit") {
- Some(unit) => match unit.as_str() {
- "cm" => match &caps.name("value") {
- Some(value) => match value.as_str().parse() {
- Ok(150..=193) => {},
- _ => continue 'validate,
- }
- _ => continue 'validate,
- },
- "in" => match &caps.name("value") {
- Some(value) => match value.as_str().parse() {
- Ok(59..=76) => {},
- _ => continue 'validate,
- },
- _ => continue 'validate,
- },
- _ => continue 'validate,
- }
- None => continue 'validate,
- }
- None => continue 'validate,
- }
- _ => continue 'validate,
- }
- // hcl (Hair Color) - a # followed by exactly six characters 0-9 or a-f.
- match passport.get("hcl") {
- Some(hcl) if hcl_re.is_match(hcl) => {},
- _ => continue 'validate,
- }
- // ecl (Eye Color) - exactly one of: amb blu brn gry grn hzl oth.
- match passport.get("ecl") {
- Some(ecl) if ecl_re.is_match(ecl) => {},
- _ => continue 'validate,
- }
- // pid (Passport ID) - a nine-digit number, including leading zeroes.
- match passport.get("pid") {
- Some(pid) if pid_re.is_match(pid) => {},
- _ => continue 'validate,
}
- // cid (Country ID) - ignored, missing or not.
valid_count += 1;
}