use aoc_runner_derive::{aoc, aoc_generator}; #[derive(Debug, PartialEq, Eq, Ord, PartialOrd)] pub struct Rule { min: usize, max: usize, ch: char, pw: String, } impl Rule { fn is_valid_part1(&self) -> bool { let n = self.pw.chars().filter(|c| *c == self.ch).count(); return n >= self.min && n <= self.max; } fn is_valid_part2(&self) -> bool { let idx_1 = self.min - 1; let idx_2 = self.max - 1; let chars: Vec = self.pw.chars().collect(); return (chars.get(idx_1) == Some(&self.ch)) ^ (chars.get(idx_2) == Some(&self.ch)); } } #[aoc_generator(day2)] pub fn input_generator(input: &str) -> Vec { input .lines() .map(|l| { let mut ws = l.trim().split_whitespace(); let range = ws.next().unwrap(); let ch = ws .next() .unwrap() .trim_end_matches(|c| c == ':') .chars() .next() .unwrap(); let pw = ws.next().unwrap().to_owned(); let (r_min, r_max) = { let mut r = range.split('-'); let r_min = r.next().unwrap().parse().unwrap(); let r_max = r.next().unwrap().parse().unwrap(); (r_min, r_max) }; Rule { min: r_min, max: r_max, ch, pw, } }) .collect::>() } #[aoc(day2, part1)] pub fn solve_part1(input: &Vec) -> usize { let mut total = 0; for rule in input { if rule.is_valid_part1() { total += 1; } } total } #[aoc(day2, part2)] pub fn solve_part2(input: &Vec) -> usize { let mut total = 0; for rule in input { if rule.is_valid_part2() { total += 1; } } total }