use std::fs; use std::fs::File; use std::io::{prelude::*, BufReader}; use std::error::Error; use regex::Regex; pub fn aoc_01_both(filename: &str) -> Result<(), Box> { let file = File::open(filename).expect("No file"); let br = BufReader::new(file); let mut v: Vec = vec![]; for line in br.lines() { v.push(line? .trim() .parse().unwrap()); } for i in 0..v.len()-2 { for j in i+1..v.len()-1 { if v[i] + v[j] == 2020 { println!("aoc_01_01 result: {}", v[i]*v[j]); } } } for i in 0..v.len()-3 { for j in i+1..v.len()-2 { for k in j+1..v.len()-1 { if v[i] + v[j] + v[k] == 2020 { println!("aoc_01_02 result: {}", v[i] * v[j] * v[k]); } } } } return Ok(()); } pub fn aoc_02(filename: &str) -> Result<(), Box> { let contents = fs::read_to_string(filename)?; let pairs: Vec> = 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>) -> Result<(), Box> { 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::().unwrap(); let max = rule[2].parse::().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>) -> Result<(), Box> { 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::().unwrap(); let sec = rule[2].parse::().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(()); }