-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday_12.rs
121 lines (104 loc) · 4.14 KB
/
day_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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use std::collections::HashSet;
use std::collections::VecDeque;
pub fn run() {
let input_str = include_str!("../../inputs/input_12.txt");
// make input into list of sums of calories
let input: Vec<Vec<char>> = input_str
.lines()
.map(|s| s.chars().collect())
.collect();
part_one(&input);
part_two(&input);
}
fn part_one(input: &[Vec<char>]) {
let mut visited_nodes: HashSet<(usize, usize)> = HashSet::new();
let mut paths: VecDeque<Vec<(usize, usize)>> = VecDeque::new();
let mut start_node: (usize, usize) = (0, 0);
'outer: for (row_index, row) in input.iter().enumerate() {
for (column_index, &column) in row.iter().enumerate() {
if column == 'S' {
start_node = (row_index, column_index);
break 'outer;
}
}
}
visited_nodes.insert(start_node);
paths.push_back(vec!(start_node));
'outer: loop {
let path = paths[0].clone();
let current_node = path.last().unwrap();
let current_node_val = match input[current_node.0][current_node.1] {
'S' => 'a',
x => x,
};
for (row_offset, column_offset) in &[(0, 1), (2, 1), (1, 0), (1, 2)] {
if current_node.0 + row_offset == 0 || current_node.0 + row_offset > input.len() ||
current_node.1 + column_offset == 0 || current_node.1 + column_offset > input[0].len()
{
continue;
}
let coord = (current_node.0 + row_offset-1, current_node.1 + column_offset-1);
let cell = input[current_node.0 + row_offset-1][current_node.1 + column_offset-1];
if !visited_nodes.contains(&coord) && (cell == current_node_val ||
cell as u32 <= current_node_val as u32 + 1 ||
(cell == 'E' && current_node_val >= 'y'))
{
visited_nodes.insert(coord);
let mut new_path = path.clone();
new_path.push(coord);
paths.push_back(new_path);
if cell == 'E' {
break 'outer;
}
}
}
paths.pop_front();
}
println!("Part one: {}", paths.pop_back().unwrap().len() - 1);
}
fn part_two(input: &[Vec<char>]) {
let mut visited_nodes: HashSet<(usize, usize)> = HashSet::new();
let mut paths: VecDeque<Vec<(usize, usize)>> = VecDeque::new();
let mut start_node: (usize, usize) = (0, 0);
'outer: for (row_index, row) in input.iter().enumerate() {
for (column_index, &column) in row.iter().enumerate() {
if column == 'E' {
start_node = (row_index, column_index);
break 'outer;
}
}
}
visited_nodes.insert(start_node);
paths.push_back(vec!(start_node));
'outer: loop {
let path = paths[0].clone();
let current_node = path.last().unwrap();
let current_node_val = match input[current_node.0][current_node.1] {
'E' => 'z',
x => x,
};
for (row_offset, column_offset) in &[(0, 1), (2, 1), (1, 0), (1, 2)] {
if current_node.0 + row_offset == 0 || current_node.0 + row_offset > input.len() ||
current_node.1 + column_offset == 0 || current_node.1 + column_offset > input[0].len()
{
continue;
}
let coord = (current_node.0 + row_offset-1, current_node.1 + column_offset-1);
let cell = input[current_node.0 + row_offset-1][current_node.1 + column_offset-1];
if !visited_nodes.contains(&coord) && (cell == current_node_val ||
cell as u32 >= current_node_val as u32 - 1 ||
(current_node_val == 'b' && cell == 'S'))
{
visited_nodes.insert(coord);
let mut new_path = path.clone();
new_path.push(coord);
paths.push_back(new_path);
if cell == 'a' || cell == 'S' {
break 'outer;
}
}
}
paths.pop_front();
}
println!("Part two: {}", paths.pop_back().unwrap().len() - 1);
}