From c350dea4a353272323c2dd3a64fbfa2759f1330d Mon Sep 17 00:00:00 2001 From: dolphinau Date: Fri, 5 Dec 2025 13:25:36 +0100 Subject: [PATCH] Add part 2 of day 4 with BTreeSet --- AoC_2025/src/days/day04.rs | 68 ++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/AoC_2025/src/days/day04.rs b/AoC_2025/src/days/day04.rs index 9d60026..932be1d 100644 --- a/AoC_2025/src/days/day04.rs +++ b/AoC_2025/src/days/day04.rs @@ -1,39 +1,65 @@ use crate::days::Solution; use std::cmp::{max, min}; +use std::collections::BTreeSet; pub struct Day04; impl Solution for Day04 { - type Input = Vec>; + type Input = (BTreeSet<(usize, usize)>, usize); fn parse(&self, data: &str) -> Self::Input { - data.split("\n") - .filter(|s| !s.is_empty()) - .map(|s| s.chars().map(|c| c == '@').collect()) - .collect() + let splited: Vec<&str> = data.split("\n").collect(); + ( + BTreeSet::from_iter( + splited + .iter() + .filter(|s| !s.is_empty()) + .enumerate() + .flat_map(|(x, l)| { + l.chars() + .enumerate() + .filter(|(_, c)| *c == '@') + .map(move |(y, _)| (x, y)) + .collect::>() + }), + ), + 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> { + let new = BTreeSet::from_iter( input .iter() - .enumerate() - .map(|(x, l)| { - l.iter() - .enumerate() - .filter(move |(y, v)| { - **v && neighbors((x, *y), input.len()) - .iter() - .filter(|(nx, ny)| input[*nx][*ny]) - .count() - < 4 - }) + .filter(|(x, y)| { + neighbors((*x, *y), size) + .iter() + .filter(|(nx, ny)| input.contains(&(*nx, *ny))) .count() + >= 4 }) - .sum() - } + .cloned(), + ); - fn part2(&self, input: &Self::Input) -> usize { - 0 + if new.len() == input.len() { + None + } else { + Some(new) } }