51 lines
1.7 KiB
Rust
51 lines
1.7 KiB
Rust
use std::fs;
|
|
use std::error::Error;
|
|
use regex::Regex;
|
|
|
|
pub fn both(filename: &str) -> Result<(), Box<dyn Error>> {
|
|
let contents = fs::read_to_string(filename)?;
|
|
let pairs: Vec<Vec<String>> = contents.lines().map(|line| {
|
|
line.split(":").map(|s| String::from(s)).collect()
|
|
}).collect();
|
|
|
|
aoc_02_01(&pairs).unwrap();
|
|
aoc_02_02(&pairs).unwrap();
|
|
Ok(())
|
|
}
|
|
|
|
fn aoc_02_01(pairs: &Vec<Vec<String>>) -> Result<(), Box<dyn Error>> {
|
|
let mut valid = 0;
|
|
let rules_re = Regex::new(r"(\d*)-(\d*) ([a-z])").unwrap();
|
|
for i in 0..pairs.len() {
|
|
let rule = rules_re.captures(&pairs[i][0]).unwrap();
|
|
let min = rule[1].parse::<usize>().unwrap();
|
|
let max = rule[2].parse::<usize>().unwrap();
|
|
let matches: usize = pairs[i][1].matches(&rule[3]).count();
|
|
if matches >= min && matches <= max {
|
|
valid += 1;
|
|
}
|
|
}
|
|
|
|
println!("2_1 had {}/{} valid passwords", valid, pairs.len());
|
|
return Ok(());
|
|
}
|
|
|
|
fn aoc_02_02(pairs: &Vec<Vec<String>>) -> Result<(), Box<dyn Error>> {
|
|
let mut valid = 0;
|
|
let rules_re = Regex::new(r"(\d*)-(\d*) ([a-z])").unwrap();
|
|
for i in 0..pairs.len() {
|
|
let rule = rules_re.captures(&pairs[i][0]).unwrap();
|
|
let first = rule[1].parse::<usize>().unwrap();
|
|
let sec = rule[2].parse::<usize>().unwrap();
|
|
|
|
// the indexes are 1 based but the pairs[x][2] has a leading space so it works out... -_-;
|
|
let m1 = pairs[i][1].as_bytes()[first] == rule[3].as_bytes()[0];
|
|
let m2 = pairs[i][1].as_bytes()[sec] == rule[3].as_bytes()[0];
|
|
if (m1 || m2) && !(m1 && m2) {
|
|
valid += 1;
|
|
}
|
|
}
|
|
|
|
println!("2_2 had {}/{} valid passwords", valid, pairs.len());
|
|
return Ok(());
|
|
} |