1use crate::util::grid::*;
3use crate::util::point::*;
4
5type Input = (u64, u64);
6
7pub fn parse(input: &str) -> Input {
8 let grid = Grid::parse(input);
9 let bottom = grid.height - 1;
10 let mut right = grid.width;
11
12 let block = |(part_one, part_two), left| {
13 let rows = (0..bottom).map(|y| (left..right).fold(0, |num, x| acc(&grid, num, x, y)));
14 let cols = (left..right).map(|x| (0..bottom).fold(0, |num, y| acc(&grid, num, x, y)));
15
16 let plus = grid[Point::new(left, bottom)] == b'+';
17 let first: u64 = if plus { rows.sum() } else { rows.product() };
18 let second: u64 = if plus { cols.sum() } else { cols.product() };
19
20 right = left - 1;
21 (part_one + first, part_two + second)
22 };
23
24 (0..grid.width).rev().filter(|&x| grid[Point::new(x, bottom)] != b' ').fold((0, 0), block)
25}
26
27pub fn part1(input: &Input) -> u64 {
28 input.0
29}
30
31pub fn part2(input: &Input) -> u64 {
32 input.1
33}
34
35fn acc(grid: &Grid<u8>, number: u64, x: i32, y: i32) -> u64 {
36 let digit = grid[Point::new(x, y)];
37 if digit == b' ' { number } else { 10 * number + u64::from(digit - b'0') }
38}