year2025/
day03.rs

1use utils::prelude::*;
2
3/// Finding the maximum number from ordered digits.
4#[derive(Clone, Debug)]
5pub struct Day03<'a> {
6    lines: Vec<&'a [u8]>,
7}
8
9impl<'a> Day03<'a> {
10    pub fn new(input: &'a str, _: InputType) -> Result<Self, InputError> {
11        let lines: Vec<&[u8]> = input.lines().map(str::as_bytes).collect();
12        for &line in &lines {
13            if let Some(&b) = line.iter().find(|x| !matches!(x, b'1'..=b'9')) {
14                return Err(InputError::new(input, b as char, "expected digit 1-9"));
15            }
16            if line.len() < 12 {
17                return Err(InputError::new(input, line, "expected at least 12 digits"));
18            }
19        }
20        Ok(Self { lines })
21    }
22
23    #[must_use]
24    pub fn part1(&self) -> u64 {
25        self.output_joltage::<2>()
26    }
27
28    #[must_use]
29    pub fn part2(&self) -> u64 {
30        self.output_joltage::<12>()
31    }
32
33    fn output_joltage<const N: usize>(&self) -> u64 {
34        let mut sum = 0;
35        for line in &self.lines {
36            let (mut start, mut joltage) = (0, 0);
37            for i in 0..N {
38                let (max_byte, start_offset) =
39                    line[start..line.len() - N + 1 + i].iter().enumerate().fold(
40                        (0, 0),
41                        |(max, offset), (i, &b)| {
42                            if b > max { (b, i) } else { (max, offset) }
43                        },
44                    );
45                joltage = (joltage * 10) + (max_byte - b'0') as u64;
46                start += start_offset + 1;
47            }
48            sum += joltage;
49        }
50        sum
51    }
52}
53
54examples!(Day03<'_> -> (u64, u64) [
55    {
56        input: "987654321111111\n811111111111119\n234234234234278\n818181911112111",
57        part1: 357,
58        part2: 3121910778619,
59    },
60]);