aoc/year2024/
day05.rs

1//! # Print Queue
2//!
3//! The input is constructed so that each possible pair that occurs in a row has a defined
4//! ordering that enables sorting with a custom `Ordering` definition. Numbers are always
5//! 2 digits so storing ordering in a fixed size 100 x 100 array is faster than using a `HashMap`.
6use crate::util::iter::*;
7use crate::util::parse::*;
8use std::cmp::Ordering::*;
9
10type Input = (usize, usize);
11
12pub fn parse(input: &str) -> Input {
13    let (prefix, suffix) = input.split_once("\n\n").unwrap();
14    let mut order = [[Greater; 100]; 100];
15
16    for [from, to] in prefix.iter_unsigned::<usize>().chunk::<2>() {
17        order[from][to] = Less;
18    }
19
20    let mut update = Vec::new();
21    let mut part_one = 0;
22    let mut part_two = 0;
23
24    for line in suffix.lines() {
25        update.clear();
26        update.extend(line.iter_unsigned::<usize>());
27        let middle = update.len() / 2;
28
29        if update.is_sorted_by(|&from, &to| order[from][to] == Less) {
30            part_one += update[middle];
31        } else {
32            // We only need the middle index so this is slightly faster than "sort_unstable_by"
33            update.select_nth_unstable_by(middle, |&from, &to| order[from][to]);
34            part_two += update[middle];
35        }
36    }
37
38    (part_one, part_two)
39}
40
41pub fn part1(input: &Input) -> usize {
42    input.0
43}
44
45pub fn part2(input: &Input) -> usize {
46    input.1
47}