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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
use std::collections::{HashMap, HashSet};
static DAY: u8 = 5;
fn main() {
let input = advent::read_file(DAY);
println!("{DAY}a: {}", PageOrdering::new(&input).right_order_middle());
println!("{DAY}b: {}", 0);
}
struct PageOrdering {
rules: HashMap<u32,HashSet<u32>>,
updates: Vec<Vec<u32>>,
}
impl PageOrdering {
fn new(input: &str) -> PageOrdering {
let (rules_lines, updates_lines) = input.split_once("\n\n").unwrap();
let mut rules = HashMap::new();
for rule in rules_lines.split("\n") {
let (left, right) = rule.split_once("|").unwrap();
let left = left.parse::<u32>().unwrap();
let right = right.parse::<u32>().unwrap();
rules.entry(left).or_insert(HashSet::new()).insert(right);
}
let mut updates = Vec::new();
for line in updates_lines.split_terminator("\n") {
let update = line.split(",").map(|x| x.parse::<u32>().unwrap()).collect::<Vec<_>>();
updates.push(update);
}
PageOrdering { rules, updates }
}
fn correct_order(&self, update: &[u32]) -> bool {
for (i, page1) in update.iter().enumerate() {
for page2 in update.iter().skip(i+1) {
let before2 = match self.rules.get(page2) {
Some(r) => r,
None => continue,
};
if before2.contains(page1) {
return false;
}
}
}
true
}
fn right_order_middle(&self) -> u32 {
let mut sum = 0;
for update in &self.updates {
if self.correct_order(update) {
sum += update[update.len()/2];
}
}
sum
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
let input =
"47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13
75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47";
assert_eq!(PageOrdering::new(input).right_order_middle(), 143);
}
}
|