1use utils::geometry::Vec2;
2use utils::grid;
3use utils::prelude::*;
4
5#[derive(Clone, Debug)]
7pub struct Day03 {
8 part1: u64,
9 part2: u64,
10}
11
12const SLOPES: [Vec2<usize>; 5] = [
13 Vec2::new(1, 1),
14 Vec2::new(3, 1),
15 Vec2::new(5, 1),
16 Vec2::new(7, 1),
17 Vec2::new(1, 2),
18];
19
20impl Day03 {
21 pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
22 let mut counts = [0; SLOPES.len()];
23 grid::for_each_row(
24 input,
25 |b| matches!(b, b'.' | b'#'),
26 || "expected '.' or '#'",
27 |row, cols, trees| {
28 for (delta, count) in SLOPES.into_iter().zip(counts.iter_mut()) {
29 if row.is_multiple_of(delta.y) {
30 let col = ((row / delta.y) * delta.x) % cols;
31 *count += u64::from(trees[col] == b'#');
32 }
33 }
34 Ok(())
35 },
36 )?;
37
38 Ok(Self {
39 part1: counts[1],
40 part2: counts.iter().product(),
41 })
42 }
43
44 #[must_use]
45 pub fn part1(&self) -> u64 {
46 self.part1
47 }
48
49 #[must_use]
50 pub fn part2(&self) -> u64 {
51 self.part2
52 }
53}
54
55examples!(Day03 -> (u64, u64) [
56 {file: "day03_example0.txt", part1: 7, part2: 336},
57]);