aoc/src/day2.rs
2020-12-04 16:50:04 -08:00

54 lines
1.5 KiB
Rust

use aoc_runner_derive::aoc;
struct PasswdEntry<'a> {
lower_bound: usize,
upper_bound: usize,
policy_char: u8,
passwd: &'a [u8],
}
impl<'a> PasswdEntry<'a> {
fn parse(mut input: &'a str) -> Option<Self> {
let lb_idx = input.find('-')?;
let lower_bound: usize = (&input[..lb_idx]).parse().ok()?;
input = &input[lb_idx + 1..];
let ub_idx = input.find(' ')?;
let upper_bound: usize = (&input[..ub_idx]).parse().ok()?;
input = &input[ub_idx + 1..];
let policy_char = input.as_bytes()[0];
let passwd = &input[3..].as_bytes();
Some(PasswdEntry {
lower_bound,
upper_bound,
policy_char,
passwd,
})
}
}
#[aoc(day2, part1)]
pub fn solve_d2_p1(input: &str) -> usize {
fn line_is_valid(line: &str) -> bool {
let entry = PasswdEntry::parse(line).unwrap();
let count = entry
.passwd
.iter()
.filter(|&&b| b == entry.policy_char)
.count();
(count >= entry.lower_bound) && (count <= entry.upper_bound)
}
input.split('\n').filter(|x| line_is_valid(x)).count()
}
#[aoc(day2, part2)]
pub fn solve_d2_p2(input: &str) -> usize {
fn line_is_valid(line: &str) -> bool {
let entry = PasswdEntry::parse(line).unwrap();
(entry.passwd[entry.lower_bound - 1] == entry.policy_char)
^ (entry.passwd[entry.upper_bound - 1] == entry.policy_char)
}
input.split('\n').filter(|x| line_is_valid(x)).count()
}