1use crate::util::grid::*;
14use crate::util::parse::*;
15use crate::util::point::*;
16
17type Input = (u64, u64);
18
19pub fn parse(input: &str) -> Input {
20 let grid = Grid::parse(input);
21 let bottom = grid.height - 1;
22 let mut right = grid.width;
23 let mut part_one = 0;
24 let mut part_two = 0;
25
26 for left in (0..grid.width).rev().filter(|&x| grid[Point::new(x, bottom)] != b' ') {
28 let rows = (0..bottom).map(|y| (left..right).fold(0, |num, x| acc(&grid, num, x, y)));
29 let cols = (left..right).map(|x| (0..bottom).fold(0, |num, y| acc(&grid, num, x, y)));
30
31 let plus = grid[Point::new(left, bottom)] == b'+';
33 part_one += if plus { rows.sum::<u64>() } else { rows.product() };
34 part_two += if plus { cols.sum::<u64>() } else { cols.product() };
35
36 right = left - 1;
37 }
38
39 (part_one, part_two)
40}
41
42pub fn part1(input: &Input) -> u64 {
43 input.0
44}
45
46pub fn part2(input: &Input) -> u64 {
47 input.1
48}
49
50fn acc(grid: &Grid<u8>, number: u64, x: i32, y: i32) -> u64 {
52 let digit = grid[Point::new(x, y)];
53 if digit == b' ' { number } else { 10 * number + digit.to_decimal::<u64>() }
54}