use std::{collections::BTreeMap, println}; #[macro_use] extern crate scan_fmt; fn main() { let required_fields = ["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"]; let contents = std::fs::read_to_string("input").unwrap(); let mut d = BTreeMap::new(); let mut valid_count = 0; for line in contents.lines() { if line.len() > 0 { let seg = line.split(" "); for s in seg { let kv: Vec<_> = s.split(":").collect(); d.insert(kv[0].to_string(), kv[1].to_string()); } } else { let mut approved = true; for field in required_fields.iter() { if !d.contains_key(field.to_string().as_str()) { println!("Didn't find key {}", field); approved = false; } } for (key, val) in &d { if !approved { println!("Not Approved! {:?}", d); break; } match key.as_str() { "byr" => { let byr = val.parse::().unwrap(); let minmax = 1920..=2002; if !minmax.contains(&byr) { approved = false; } } "iyr" => { let iyr = val.parse::().unwrap(); let minmax = 2010..=2020; if !minmax.contains(&iyr) { approved = false; } } "eyr" => { let eyr = val.parse::().unwrap(); let minmax = 2020..=2030; if !minmax.contains(&eyr) { approved = false; } } "hgt" => { if let Ok((hgt, unit)) = scan_fmt!(&val, "{d}{}", i32, String) { match unit.as_str() { "cm" => { let minmax = 150..=193; if !minmax.contains(&hgt) { approved = false; } } "in" => { let minmax = 59..=76; if !minmax.contains(&hgt) { approved = false; } } _ => { println!("malformed hgt value: {}:{}", key, val); approved = false; } } } } "hcl" => { let hcl = scan_fmt!(&val, "#{[0-9a-f]}", String); match hcl { Ok(v) => { if !v.len() == 6 { approved = false; } } Err(_) => { println!("malformed hcl value: {}:{}", key, val); approved = false; } } } "ecl" => { let valid_ecl = ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"]; if !valid_ecl.contains(&val.as_str()) { approved = false; } } "pid" => { let pid = scan_fmt!(&val, "{[0-9]}", String); match pid { Ok(v) => { if v.len() < 9 || v.len() > 9 { approved = false; } else { println!("pid = {:?} {}", v, v.len()); } } Err(_) => { println!("malformed pid value: {}:{}", key, val); approved = false; } } } "cid" => println!("cid"), _ => approved = false, } } if approved && (d.len() >= 7 && d.len() <= 8) { valid_count += 1; // if d.contains_key("cid") { println!("Approved! {:?}", d); // } } println!("clearing {:?}", d); d.clear(); } } // past guesses: // 264, < // 195, < // 191 // 187 // 186 // 185 // 156 // 152 // 148 // 102 // 78 println!("Found {} approved passports", valid_count - 1); }