From 8496bcfdee1d077615bb72341200fb29c1cf2798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20M=C3=BCller?= Date: Sat, 7 Feb 2026 17:27:09 +0100 Subject: [PATCH] Add solution for "Day 6: Trash Compactor", part 2 --- README.md | 2 + src/solvers/trash_compactor.rs | 96 +++++++++++++++++++++++++++------- tests/examples.rs | 2 +- tests/full_data.rs | 2 +- 4 files changed, 81 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 3ec795d..397a8a0 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,8 @@ From the input data, we construct a [`MultiInterval`](src/common/interval.rs), w :mag_right: Puzzle: , :white_check_mark: Solver: [`TrashCompactor`](src/solvers/trash_compactor.rs) +We implement two different ways to collect numbers from the input. For part 1, numbers separated by space are read line by line, stored in a two-dimensional array and then aggregated in columns. While for part 2, each column of characters in the input data represents a number, and empty columns are interpreted as the separators between blocks for aggregation. + ### Day 8: Playground :mag_right: Puzzle: , :white_check_mark: Solver: [`Playground`](src/solvers/playground.rs) diff --git a/src/solvers/trash_compactor.rs b/src/solvers/trash_compactor.rs index 261314f..39a7ca9 100644 --- a/src/solvers/trash_compactor.rs +++ b/src/solvers/trash_compactor.rs @@ -1,11 +1,74 @@ use crate::solvers::Solver; -use grid::*; +use grid::Grid; use std::io::BufRead; pub struct TrashCompactor {} impl TrashCompactor { const NUMBER_SPLIT_CHAR: char = ' '; + const SUM_SIGN: &'static str = "+"; + const PRODUCT_SIGN: &'static str = "*"; + + fn add_row_layout_line(line: &str, numbers: &mut Grid) { + let v: Vec = line + .split(Self::NUMBER_SPLIT_CHAR) + .filter_map(|s| { + if s.is_empty() { + None + } else { + Some(s.parse().unwrap()) + } + }) + .collect(); + numbers.push_row(v); + } + + fn row_layout_calculation(numbers: &Grid, signs: &Vec<&str>) -> u64 { + let mut result = 0; + for (i, sign) in signs.iter().enumerate() { + match *sign { + Self::SUM_SIGN => result += numbers.iter_col(i).sum::(), + Self::PRODUCT_SIGN => result += numbers.iter_col(i).product::(), + _ => {} + } + } + result + } + + fn add_column_layout_line(line: &str, numbers: &mut Vec) { + let add = line + .bytes() + .map(|c| if c.is_ascii_digit() { c - b'0' } else { 0 }) + .collect::>(); + if numbers.len() < 1 { + *numbers = vec![0; add.len()]; + } + for (i, n) in numbers.iter_mut().enumerate() { + if add[i] > 0 { + *n = *n * 10 + add[i] as u64; + } + } + } + + fn column_layout_calculation(numbers: &Vec, signs: &Vec<&str>) -> u64 { + let mut result = 0; + let mut it = numbers.iter(); + for sign in signs { + let block_it = it.by_ref().take_while(|&&n| n > 0); + match *sign { + Self::SUM_SIGN => result += block_it.sum::(), + Self::PRODUCT_SIGN => result += block_it.product::(), + _ => {} + } + } + result + } + + fn signs(line: &str) -> Vec<&str> { + line.split(Self::NUMBER_SPLIT_CHAR) + .filter(|s| !s.is_empty()) + .collect() + } } impl Solver for TrashCompactor { @@ -13,26 +76,21 @@ impl Solver for TrashCompactor { const PUZZLE_NAME: &'static str = "Trash Compactor"; fn process_data(&self, reader: R) -> (u64, u64) { - let mut part1 = 0; - let mut grid = Grid::new(0, 0); + let mut row_layout_result = 0; + let mut column_layout_result = 0; + let mut row_layout_numbers = Grid::new(0, 0); + let mut column_layout_numbers = Vec::new(); for line in reader.lines().map_while(Result::ok) { - let v: Vec<&str> = line - .split(Self::NUMBER_SPLIT_CHAR) - .filter(|s| !s.is_empty()) - .collect(); - match v[0].parse::() { - Ok(_) => grid.push_row(v.iter().map(|n| n.parse::().unwrap()).collect()), - Err(_) => { - for (i, sign) in v.iter().enumerate() { - if *sign == "+" { - part1 += grid.iter_col(i).sum::(); - } else { - part1 += grid.iter_col(i).product::(); - } - } - } + if line.as_bytes()[0].is_ascii_digit() || line.as_bytes()[0].is_ascii_whitespace() { + Self::add_row_layout_line(&line, &mut row_layout_numbers); + Self::add_column_layout_line(&line, &mut column_layout_numbers); + } else { + let signs = Self::signs(&line); + row_layout_result = Self::row_layout_calculation(&row_layout_numbers, &signs); + column_layout_result = + Self::column_layout_calculation(&column_layout_numbers, &signs); } } - (part1, 0) + (row_layout_result, column_layout_result) } } diff --git a/tests/examples.rs b/tests/examples.rs index 4b3febd..196a1bf 100644 --- a/tests/examples.rs +++ b/tests/examples.rs @@ -54,7 +54,7 @@ fn cafeteria() { #[test] fn trash_compactor() { assert_eq!( - Ok((4277556, 0)), + Ok((4277556, 3263827)), solvers::run_solver(solvers::trash_compactor::TrashCompactor {}, &EXAMPLE_PATHS) ); } diff --git a/tests/full_data.rs b/tests/full_data.rs index fc23384..63f0bb7 100644 --- a/tests/full_data.rs +++ b/tests/full_data.rs @@ -49,7 +49,7 @@ fn cafeteria() { #[test] fn trash_compactor() { assert_eq!( - Ok((8108520669952, 0)), + Ok((8108520669952, 11708563470209)), solvers::run_solver( solvers::trash_compactor::TrashCompactor {}, &solvers::DATA_PATHS