1use std::cmp::Ordering::*;
7
8use crate::util::iter::*;
9use crate::util::parse::*;
10
11type Input = (usize, usize);
12
13pub fn parse(input: &str) -> Input {
14 let (prefix, suffix) = input.split_once("\n\n").unwrap();
15 let mut order = [[Greater; 100]; 100];
16
17 for [from, to] in prefix.iter_unsigned::<usize>().chunk::<2>() {
18 order[from][to] = Less;
19 }
20
21 let mut update = Vec::new();
22 let mut part_one = 0;
23 let mut part_two = 0;
24
25 for line in suffix.lines() {
26 update.clear();
27 update.extend(line.iter_unsigned::<usize>());
28 let middle = update.len() / 2;
29
30 if update.is_sorted_by(|&from, &to| order[from][to] == Less) {
31 part_one += update[middle];
32 } else {
33 update.select_nth_unstable_by(middle, |&from, &to| order[from][to]);
35 part_two += update[middle];
36 }
37 }
38
39 (part_one, part_two)
40}
41
42pub fn part1(input: &Input) -> usize {
43 input.0
44}
45
46pub fn part2(input: &Input) -> usize {
47 input.1
48}