1use 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 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}