Day 10. Took a bit longer because I tried petgraph, which was not as helpful as I'd hoped.
This commit is contained in:
@@ -6,4 +6,5 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
nom = "6.0.1"
|
||||
petgraph = "0.5.1"
|
||||
thiserror = "1.0.22"
|
||||
93
inputs/day10.txt
Normal file
93
inputs/day10.txt
Normal file
@@ -0,0 +1,93 @@
|
||||
97
|
||||
62
|
||||
23
|
||||
32
|
||||
51
|
||||
19
|
||||
98
|
||||
26
|
||||
90
|
||||
134
|
||||
73
|
||||
151
|
||||
116
|
||||
76
|
||||
6
|
||||
94
|
||||
113
|
||||
127
|
||||
119
|
||||
44
|
||||
115
|
||||
50
|
||||
143
|
||||
150
|
||||
86
|
||||
91
|
||||
36
|
||||
104
|
||||
131
|
||||
101
|
||||
38
|
||||
66
|
||||
46
|
||||
96
|
||||
54
|
||||
70
|
||||
8
|
||||
30
|
||||
1
|
||||
108
|
||||
69
|
||||
139
|
||||
24
|
||||
29
|
||||
77
|
||||
124
|
||||
107
|
||||
14
|
||||
137
|
||||
16
|
||||
140
|
||||
80
|
||||
68
|
||||
25
|
||||
31
|
||||
59
|
||||
45
|
||||
126
|
||||
148
|
||||
67
|
||||
13
|
||||
125
|
||||
53
|
||||
57
|
||||
41
|
||||
47
|
||||
35
|
||||
145
|
||||
120
|
||||
12
|
||||
37
|
||||
5
|
||||
110
|
||||
138
|
||||
130
|
||||
2
|
||||
63
|
||||
83
|
||||
22
|
||||
79
|
||||
52
|
||||
7
|
||||
95
|
||||
58
|
||||
149
|
||||
123
|
||||
89
|
||||
109
|
||||
15
|
||||
144
|
||||
114
|
||||
9
|
||||
78
|
||||
11
inputs/day10_test1.txt
Normal file
11
inputs/day10_test1.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
16
|
||||
10
|
||||
15
|
||||
5
|
||||
1
|
||||
11
|
||||
7
|
||||
19
|
||||
6
|
||||
12
|
||||
4
|
||||
31
inputs/day10_test2.txt
Normal file
31
inputs/day10_test2.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
28
|
||||
33
|
||||
18
|
||||
42
|
||||
31
|
||||
14
|
||||
46
|
||||
20
|
||||
48
|
||||
47
|
||||
24
|
||||
23
|
||||
49
|
||||
45
|
||||
19
|
||||
38
|
||||
39
|
||||
11
|
||||
1
|
||||
32
|
||||
25
|
||||
35
|
||||
8
|
||||
17
|
||||
7
|
||||
9
|
||||
4
|
||||
2
|
||||
34
|
||||
10
|
||||
3
|
||||
109
src/bin/joltage.rs
Normal file
109
src/bin/joltage.rs
Normal file
@@ -0,0 +1,109 @@
|
||||
use advent2020::errors::TopLevelError;
|
||||
use petgraph::graphmap::GraphMap;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::str::FromStr;
|
||||
|
||||
fn visit_all_nodes(
|
||||
graph: &GraphMap<u64, u64, petgraph::Directed>,
|
||||
start: u64,
|
||||
end: u64,
|
||||
) -> Result<(usize, usize, usize), TopLevelError> {
|
||||
let mut ones = 0;
|
||||
let mut twos = 0;
|
||||
let mut threes = 0;
|
||||
let mut current = start;
|
||||
while current != end {
|
||||
let (_, next, edge_length) = graph
|
||||
.edges(current)
|
||||
.min()
|
||||
.ok_or(TopLevelError::UnknownError)?;
|
||||
match edge_length {
|
||||
0 => return Err(TopLevelError::UnknownError),
|
||||
1 => ones += 1,
|
||||
2 => twos += 1,
|
||||
3 => threes += 1,
|
||||
_ => return Err(TopLevelError::UnknownError),
|
||||
}
|
||||
current = next;
|
||||
}
|
||||
Ok((ones, twos, threes))
|
||||
}
|
||||
|
||||
fn path_counts(
|
||||
graph: &GraphMap<u64, u64, petgraph::Directed>,
|
||||
cheat_codes: &mut HashMap<u64, usize>,
|
||||
start: u64,
|
||||
end: u64,
|
||||
) -> usize {
|
||||
if start == end {
|
||||
return 1;
|
||||
}
|
||||
|
||||
let mut sum = 0;
|
||||
|
||||
for (_, to, _) in graph.edges(start) {
|
||||
match cheat_codes.get(&to) {
|
||||
None => {
|
||||
let result = path_counts(graph, cheat_codes, to, end);
|
||||
cheat_codes.insert(to, result);
|
||||
sum += result;
|
||||
}
|
||||
Some(result) => {
|
||||
sum += result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sum
|
||||
}
|
||||
|
||||
fn main() -> Result<(), TopLevelError> {
|
||||
let filename = env::args().nth(1).expect("No file argument given.");
|
||||
let contents = fs::read_to_string(filename)?;
|
||||
let mut graph = GraphMap::new();
|
||||
let mut nodes = Vec::new();
|
||||
|
||||
// add the nodes in the graph, which are weighted by their values
|
||||
let mut max_jolts = 0;
|
||||
for line in contents.lines() {
|
||||
let value = u64::from_str(line)?;
|
||||
if value > max_jolts {
|
||||
max_jolts = value;
|
||||
}
|
||||
graph.add_node(value);
|
||||
nodes.push(value);
|
||||
}
|
||||
max_jolts += 3;
|
||||
|
||||
graph.add_node(0);
|
||||
nodes.push(0); // outlet
|
||||
graph.add_node(max_jolts);
|
||||
nodes.push(max_jolts); // my device
|
||||
|
||||
for start in nodes.iter() {
|
||||
for end in nodes.iter() {
|
||||
if (*end >= (start + 1)) && (*end <= (start + 3)) {
|
||||
graph.add_edge(*start, *end, end - start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let (one_count, two_count, three_count) = visit_all_nodes(&graph, 0, max_jolts)?;
|
||||
println!("Found a path that visits all nodes:");
|
||||
println!(" jumps of size 1: {}", one_count);
|
||||
println!(" jumps of size 2: {}", two_count);
|
||||
println!(" jumps of size 3: {}", three_count);
|
||||
println!(
|
||||
" product of size 1 and size 3: {}",
|
||||
one_count * three_count
|
||||
);
|
||||
let mut cheat_codes = HashMap::with_capacity(10000);
|
||||
println!(
|
||||
"Total number of paths: {}",
|
||||
path_counts(&graph, &mut cheat_codes, 0, max_jolts)
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -40,6 +40,8 @@ pub enum TopLevelError {
|
||||
#[from]
|
||||
source: ExecutionError,
|
||||
},
|
||||
#[error("Numeric conversion error: {0}")]
|
||||
NumConversionError(#[from] ParseIntError),
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
|
||||
Reference in New Issue
Block a user