Add part 2 of day 4 with BTreeSet

This commit is contained in:
dolphinau 2025-12-05 13:25:36 +01:00
parent 182cea15a7
commit c350dea4a3

View file

@ -1,39 +1,65 @@
use crate::days::Solution; use crate::days::Solution;
use std::cmp::{max, min}; use std::cmp::{max, min};
use std::collections::BTreeSet;
pub struct Day04; pub struct Day04;
impl Solution for Day04 { impl Solution for Day04 {
type Input = Vec<Vec<bool>>; type Input = (BTreeSet<(usize, usize)>, usize);
fn parse(&self, data: &str) -> Self::Input { fn parse(&self, data: &str) -> Self::Input {
data.split("\n") let splited: Vec<&str> = data.split("\n").collect();
.filter(|s| !s.is_empty()) (
.map(|s| s.chars().map(|c| c == '@').collect()) BTreeSet::from_iter(
.collect() splited
.iter()
.filter(|s| !s.is_empty())
.enumerate()
.flat_map(|(x, l)| {
l.chars()
.enumerate()
.filter(|(_, c)| *c == '@')
.map(move |(y, _)| (x, y))
.collect::<Vec<(usize, usize)>>()
}),
),
splited.len(),
)
} }
fn part1(&self, input: &Self::Input) -> usize { fn part1(&self, (input, size): &Self::Input) -> usize {
input.len() - remove_rolls(&input, *size).unwrap_or_default().len()
}
fn part2(&self, (input, size): &Self::Input) -> usize {
let mut removed = 0;
let mut test = input.clone();
while let Some(new_input) = remove_rolls(&test, *size) {
removed += test.len() - new_input.len();
test = new_input;
}
removed
}
}
fn remove_rolls(input: &BTreeSet<(usize, usize)>, size: usize) -> Option<BTreeSet<(usize, usize)>> {
let new = BTreeSet::from_iter(
input input
.iter() .iter()
.enumerate() .filter(|(x, y)| {
.map(|(x, l)| { neighbors((*x, *y), size)
l.iter() .iter()
.enumerate() .filter(|(nx, ny)| input.contains(&(*nx, *ny)))
.filter(move |(y, v)| {
**v && neighbors((x, *y), input.len())
.iter()
.filter(|(nx, ny)| input[*nx][*ny])
.count()
< 4
})
.count() .count()
>= 4
}) })
.sum() .cloned(),
} );
fn part2(&self, input: &Self::Input) -> usize { if new.len() == input.len() {
0 None
} else {
Some(new)
} }
} }