AoC2020/src/bin/day4.rs

123 lines
3.1 KiB
Rust

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<String, String>) -> 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::<u32>() {
if year < 1920 || year > 2002 {
return 0;
}
} else {
return 0;
}
if let Ok(year) = passport.get("iyr").unwrap().parse::<u32>() {
if year < 2010 || year > 2020 {
return 0;
}
} else {
return 0;
}
if let Ok(year) = passport.get("eyr").unwrap().parse::<u32>() {
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::<u32>() {
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<dyn Error>> {
let file = File::open("inputs/day4.txt")?;
let lines = io::BufReader::new(file).lines().map(|l| l.unwrap());
let mut passports: Vec<HashMap<String, String>> = Vec::new();
let mut passport = HashMap::<String, String>::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(())
}