-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path05.rs
70 lines (61 loc) · 1.6 KB
/
05.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#![feature(test)]
use std::cmp::Ordering;
use itertools::Itertools;
use rustc_hash::FxHashSet;
struct Input {
rules: FxHashSet<Rule>,
updates: Vec<Vec<Page>>,
}
type Rule = (Page, Page);
type Page = i32;
fn setup(input: &str) -> Input {
let mut blocks = input.trim().split("\n\n");
let rules = blocks
.next()
.unwrap()
.lines()
.map(|line| {
line.split('|')
.map(|x| x.parse().unwrap())
.collect_tuple()
.unwrap()
})
.collect();
let updates = blocks
.next()
.unwrap()
.lines()
.map(|line| line.split(',').map(|x| x.parse().unwrap()).collect())
.collect();
Input { rules, updates }
}
fn make_sort_cmp(rules: &FxHashSet<Rule>) -> impl (Fn(&Page, &Page) -> Ordering) + Copy + use<'_> {
|&a, &b| match () {
_ if rules.contains(&(a, b)) => Ordering::Less,
_ if rules.contains(&(b, a)) => Ordering::Greater,
_ => Ordering::Equal,
}
}
fn part1(input: &Input) -> Page {
let cmp = make_sort_cmp(&input.rules);
input
.updates
.iter()
.filter(|&u| u.is_sorted_by(|a, b| cmp(a, b).is_le()))
.map(|u| u[u.len() >> 1])
.sum()
}
fn part2(input: &Input) -> Page {
let cmp = make_sort_cmp(&input.rules);
input
.updates
.iter()
.filter(|&u| !u.is_sorted_by(|a, b| cmp(a, b).is_le()))
.cloned()
.map(|mut u| {
let n = u.len() >> 1;
*u.select_nth_unstable_by(n, cmp).1
})
.sum()
}
aoc::main!(2024, 5, ex: 1);