1
Fork 0
advent-of-code/source/year_2020/day_02/mod.rs

61 lines
1.5 KiB
Rust

use crate::prelude::*;
pub fn solution() -> Solution {
Solution::new(Day::new(2, 2020), part_1, part_2).with_expected(638, 699)
}
#[derive(Debug)]
struct Item {
min: usize,
max: usize,
letter: String,
password: String,
}
fn parse_items(input: &str) -> Vec<Item> {
let mut items = vec![];
for line in input.lines() {
// TODO: Replace with regex.
let min = &line[0..line.find('-').unwrap()];
let max = &line[line.find('-').unwrap() + 1..line.find(' ').unwrap()];
let letter = &line[line.find(' ').unwrap() + 1..line.find(':').unwrap()];
let password = &line[line.find(": ").unwrap() + 2..];
items.push(Item {
min: min.parse().unwrap(),
max: max.parse().unwrap(),
letter: letter.to_string(),
password: password.to_string(),
})
}
items
}
fn part_1(input: &str) -> Result<String> {
Ok(
parse_items(input)
.into_iter()
.filter(|item| item.password.matches(&item.letter).count() >= item.min)
.filter(|item| item.password.matches(&item.letter).count() <= item.max)
.count()
.to_string(),
)
}
fn part_2(input: &str) -> Result<String> {
Ok(
parse_items(input)
.into_iter()
.filter(|item| {
let letter = item.letter.chars().next();
let target_one = item.password.chars().nth(item.min - 1);
let target_two = item.password.chars().nth(item.max - 1);
target_one != target_two
&& (target_one == letter || target_two == letter)
})
.count()
.to_string(),
)
}