-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path12.rs
79 lines (68 loc) · 1.84 KB
/
12.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
71
72
73
74
75
76
77
78
79
#![feature(test)]
use rustc_hash::{FxHashMap, FxHashSet};
type Input = FxHashMap<i32, Vec<i32>>;
fn setup(input: &str) -> Input {
let mut out = FxHashMap::default();
let mut map = FxHashMap::default();
map.insert("start", 0);
map.insert("end", 1);
for line in input.trim().lines() {
let mut split = line.split('-').map(|x| {
if !map.contains_key(x) {
map.insert(x, (map.len() as i32) * if x < "a" { 1 } else { -1 });
}
*map.get(x).unwrap()
});
let a = split.next().unwrap();
let b = split.next().unwrap();
match out.get_mut(&a) {
None => {
out.insert(a, vec![b]);
}
Some(x) => {
x.push(b);
}
}
match out.get_mut(&b) {
None => {
out.insert(b, vec![a]);
}
Some(x) => {
x.push(a);
}
}
}
out
}
fn search(node: i32, graph: &Input, visited: &mut FxHashSet<i32>, small_twice: bool) -> u32 {
if node == 1 {
return 1;
}
let mut twice = false;
if node <= 0 && visited.contains(&node) {
if small_twice || node == 0 {
return 0;
}
twice = true;
}
visited.insert(node);
let out = match graph.get(&node) {
None => 0,
Some(edges) => edges
.iter()
.cloned()
.map(|next| search(next, graph, visited, twice || small_twice))
.sum::<u32>(),
};
if !twice {
visited.remove(&node);
}
out
}
fn part1(input: &Input) -> String {
search(0, input, &mut FxHashSet::default(), true).to_string()
}
fn part2(input: &Input) -> String {
search(0, input, &mut FxHashSet::default(), false).to_string()
}
aoc::main!(2021, 12, ex: 1, 2, 3);