year2024/
day01.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use utils::prelude::*;

/// Comparing two lists of numbers.
#[derive(Clone, Debug)]
pub struct Day01 {
    left: Vec<u32>,
    right: Vec<u32>,
}

impl Day01 {
    pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
        let pairs = parser::u32()
            .then(parser::u32().with_prefix("   "))
            .parse_lines(input)?;

        let mut left = pairs.iter().map(|x| x.0).collect::<Vec<_>>();
        left.sort_unstable();

        let mut right = pairs.into_iter().map(|x| x.1).collect::<Vec<_>>();
        right.sort_unstable();

        Ok(Self { left, right })
    }

    #[must_use]
    pub fn part1(&self) -> u32 {
        self.left
            .iter()
            .zip(&self.right)
            .map(|(&l, &r)| l.abs_diff(r))
            .sum()
    }

    #[must_use]
    pub fn part2(&self) -> u32 {
        let mut score = 0;
        let mut i = 0;
        for &l in &self.left {
            while i < self.right.len() && self.right[i] < l {
                i += 1;
            }

            let mut j = i;
            while j < self.right.len() && self.right[j] == l {
                score += l;
                j += 1;
            }
        }
        score
    }
}

examples!(Day01 -> (u32, u32) [
    {input: "3   4\n4   3\n2   5\n1   3\n3   9\n3   3", part1: 11, part2: 31},
]);