97 lines
3.1 KiB
Rust
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)
|
|
}
|
|
}
|