1
0
Files
AdventOfCode2025/src/solvers/trash_compactor.rs
T
2026-02-07 17:27:09 +01:00

97 lines
3.1 KiB
Rust

use crate::solvers::Solver;
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<u64>) {
let v: Vec<u64> = 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<u64>, 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::<u64>(),
Self::PRODUCT_SIGN => result += numbers.iter_col(i).product::<u64>(),
_ => {}
}
}
result
}
fn add_column_layout_line(line: &str, numbers: &mut Vec<u64>) {
let add = line
.bytes()
.map(|c| if c.is_ascii_digit() { c - b'0' } else { 0 })
.collect::<Vec<u8>>();
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<u64>, 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::<u64>(),
Self::PRODUCT_SIGN => result += block_it.product::<u64>(),
_ => {}
}
}
result
}
fn signs(line: &str) -> Vec<&str> {
line.split(Self::NUMBER_SPLIT_CHAR)
.filter(|s| !s.is_empty())
.collect()
}
}
impl Solver for TrashCompactor {
const PUZZLE_INDEX: u8 = 6;
const PUZZLE_NAME: &'static str = "Trash Compactor";
fn process_data<R: BufRead>(&self, reader: R) -> (u64, u64) {
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) {
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);
}
}
(row_layout_result, column_layout_result)
}
}