summaryrefslogtreecommitdiff
path: root/src/bin/day5.rs
blob: d13be858d8b921ed04eb508a5d0079de4af0fffe (plain)
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);
    }
}