Add solution for "Day 6: Trash Compactor", part 2
This commit is contained in:
@@ -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<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 {
|
||||
@@ -13,26 +76,21 @@ impl Solver for TrashCompactor {
|
||||
const PUZZLE_NAME: &'static str = "Trash Compactor";
|
||||
|
||||
fn process_data<R: BufRead>(&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::<u32>() {
|
||||
Ok(_) => grid.push_row(v.iter().map(|n| n.parse::<u64>().unwrap()).collect()),
|
||||
Err(_) => {
|
||||
for (i, sign) in v.iter().enumerate() {
|
||||
if *sign == "+" {
|
||||
part1 += grid.iter_col(i).sum::<u64>();
|
||||
} else {
|
||||
part1 += grid.iter_col(i).product::<u64>();
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user