use std::collections::HashMap; use std::error::Error; use std::fs::File; use std::io::{self, BufRead}; use std::vec::Vec; #[macro_use] extern crate lazy_static; extern crate regex; use regex::Regex; fn is_valid(passport: &HashMap) -> u32 { lazy_static! { static ref HCL_RE: Regex = Regex::new(r"^#[a-f0-9]{6}$").unwrap(); static ref PID_RE: Regex = Regex::new(r"^[0-9]{9}$").unwrap(); static ref ECL_RE: Regex = Regex::new(r"^(amb|blu|brn|gry|grn|hzl|oth)$").unwrap(); static ref HGT_RE: Regex = Regex::new(r"^([0-9]+)(in|cm)$").unwrap(); } if !passport.contains_key("byr") || !passport.contains_key("iyr") || !passport.contains_key("eyr") || !passport.contains_key("hgt") || !passport.contains_key("hcl") || !passport.contains_key("ecl") || !passport.contains_key("pid") { return 0; }; if let Ok(year) = passport.get("byr").unwrap().parse::() { if year < 1920 || year > 2002 { return 0; } } else { return 0; } if let Ok(year) = passport.get("iyr").unwrap().parse::() { if year < 2010 || year > 2020 { return 0; } } else { return 0; } if let Ok(year) = passport.get("eyr").unwrap().parse::() { if year < 2020 || year > 2030 { return 0; } } else { return 0; } if !HCL_RE.is_match(passport.get("hcl").unwrap()) { return 0; } if let Some(cap) = HGT_RE.captures_iter(passport.get("hgt").unwrap()).nth(0) { if let Ok(hgt) = cap[1].parse::() { match &cap[2] { "in" => { if hgt < 59 || hgt > 76 { return 0; } } "cm" => { if hgt < 150 || hgt > 193 { return 0; } } _ => return 0, } } else { return 0; } } else { return 0; } if !ECL_RE.is_match(passport.get("ecl").unwrap()) { return 0; } if !PID_RE.is_match(passport.get("pid").unwrap()) { return 0; } return 1; } fn main() -> Result<(), Box> { let file = File::open("inputs/day4.txt")?; let lines = io::BufReader::new(file).lines().map(|l| l.unwrap()); let mut passports: Vec> = Vec::new(); let mut passport = HashMap::::new(); for line in lines { if line == "" { passports.push(passport); passport = HashMap::new(); continue; } for tuple in line.split(" ") { let mut parts = tuple.split(":"); let key = parts.nth(0).unwrap().to_string(); let value = parts.nth(0).unwrap().to_string(); passport.insert(key, value); } } passports.push(passport); println!("Read {} passports.", passports.len()); let count = passports.iter().map(is_valid).fold(0, |acc, x| acc + x); println!("Valid count {}", count); Ok(()) }