Skip to content

Commit 2572482

Browse files
committed
finish day16
1 parent 0b7abb5 commit 2572482

File tree

2 files changed

+112
-17
lines changed

2 files changed

+112
-17
lines changed

examples/day_16.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ fn main() {
66
let lines = utils::read_lines("inputs/day_16").unwrap();
77
let (connection_map, rate_map) = parsing(&lines);
88
println!("part 1: {}", part_1(&connection_map, &rate_map));
9+
println!("part 2: {}", part_2(&connection_map, &rate_map));
910
}

src/day_16.rs

Lines changed: 111 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::cmp::max;
1+
use std::cmp::{max, min};
22
use std::collections::{HashMap, HashSet};
33
use std::str::FromStr;
44
use anyhow::{anyhow, Result, Error};
@@ -19,8 +19,8 @@ pub fn parsing(lines: &Vec<String>) -> (HashMap<String, Vec<String>>, HashMap<St
1919
}
2020

2121

22-
fn dfs(
23-
best_records: &mut HashMap<(String, usize), usize>,
22+
fn dfs_1(
23+
best_records: &mut HashMap<(String, bool, usize), usize>,
2424
mins_left: usize,
2525
pos: String,
2626
mut opened_valves: HashSet<String>,
@@ -30,13 +30,20 @@ fn dfs(
3030
valve_flow_rate_mapping: &HashMap<String, usize>,
3131
num_valves_with_flow: usize,
3232
) {
33-
let record = best_records.entry((pos.clone(), mins_left)).or_insert(pressure_released);
34-
if *record <= pressure_released {
35-
*record = pressure_released;
33+
let mut cur_pos_opened;
34+
if opened_valves.contains(&pos) {
35+
cur_pos_opened = true;
3636
}
3737
else {
38+
cur_pos_opened = false;
39+
}
40+
if best_records.contains_key(&(pos.clone(), cur_pos_opened, mins_left)) && best_records[&(pos.clone(), cur_pos_opened, mins_left)] >= pressure_released {
3841
return;
3942
}
43+
else {
44+
best_records.insert((pos.clone(), cur_pos_opened, mins_left), pressure_released);
45+
}
46+
4047
if mins_left == 0 || mins_left - 1 == 0 {
4148
pressure_records.push(pressure_released);
4249
return
@@ -47,25 +54,115 @@ fn dfs(
4754
}
4855

4956
for neighbor in &valves_connection_mapping[&pos] {
50-
dfs(best_records, mins_left-1, neighbor.to_owned(), opened_valves.clone(), pressure_records, pressure_released, valves_connection_mapping, valve_flow_rate_mapping, num_valves_with_flow);
57+
dfs_1(best_records, mins_left-1, neighbor.to_owned(), opened_valves.clone(), pressure_records, pressure_released, valves_connection_mapping, valve_flow_rate_mapping, num_valves_with_flow);
5158
}
5259

53-
if valve_flow_rate_mapping[&pos] == 0 {
60+
if valve_flow_rate_mapping[&pos] == 0 || opened_valves.contains(&pos) {
5461
return;
5562
}
63+
opened_valves.insert(pos.clone());
64+
dfs_1(best_records, mins_left-1, pos.to_owned(), opened_valves.clone(), pressure_records, pressure_released + valve_flow_rate_mapping[&pos] * (mins_left-1), valves_connection_mapping, valve_flow_rate_mapping, num_valves_with_flow);
65+
}
66+
67+
pub fn part_1(valves_connection_mapping: &HashMap<String, Vec<String>>, valve_flow_rate_mapping: &HashMap<String, usize>) -> usize {
68+
let num_valves_with_flow = valve_flow_rate_mapping
69+
.values()
70+
.map(|x| {
71+
if *x > 0 {
72+
1
73+
}
74+
else {
75+
0
76+
}
77+
})
78+
.sum();
79+
let mut pressure_records = vec![];
80+
let mut best_records = HashMap::new();
81+
dfs_1(&mut best_records, MINUTES, "AA".to_owned(), HashSet::new(), &mut pressure_records, 0, valves_connection_mapping, valve_flow_rate_mapping, num_valves_with_flow);
82+
pressure_records.into_iter().max().unwrap()
83+
}
84+
85+
fn dfs_2(
86+
best_records: &mut HashMap<(String, String, bool, bool, usize), usize>,
87+
mins_left: usize,
88+
pos: String,
89+
epos: String, // elephant pos
90+
mut opened_valves: HashSet<String>,
91+
pressure_records: &mut Vec<usize>,
92+
pressure_released: usize,
93+
valves_connection_mapping: &HashMap<String, Vec<String>>,
94+
valve_flow_rate_mapping: &HashMap<String, usize>,
95+
num_valves_with_flow: usize,
96+
) {
97+
let mut cur_pos_opened;
5698
if opened_valves.contains(&pos) {
99+
cur_pos_opened = true;
100+
}
101+
else {
102+
cur_pos_opened = false;
103+
}
104+
let mut cur_epos_opened;
105+
if opened_valves.contains(&epos) {
106+
cur_epos_opened = true;
107+
}
108+
else {
109+
cur_epos_opened = false;
110+
}
111+
// if released pressure is lower than the same positions at the same time, no need to continue on this path
112+
if best_records.contains_key(&(pos.clone(), epos.clone(), cur_pos_opened, cur_epos_opened, mins_left)) && best_records[&(pos.clone(), epos.clone(), cur_pos_opened, cur_epos_opened, mins_left)] >= pressure_released {
57113
return;
58114
}
59115
else {
60-
opened_valves.insert(pos.clone());
116+
// pos and epos are mirrored
117+
best_records.insert((pos.clone(), epos.clone(), cur_pos_opened, cur_epos_opened, mins_left), pressure_released);
118+
best_records.insert((epos.clone(), pos.to_owned(), cur_epos_opened, cur_pos_opened, mins_left), pressure_released);
119+
}
120+
// not enough time to make a diff
121+
if mins_left <= 1 {
122+
pressure_records.push(pressure_released);
123+
return
124+
}
125+
// all valves which can release pressure have been opened
126+
if opened_valves.len() == num_valves_with_flow {
127+
pressure_records.push(pressure_released);
128+
return
61129
}
62130

131+
// if neither choose to open valves
63132
for neighbor in &valves_connection_mapping[&pos] {
64-
dfs(best_records, mins_left-2, neighbor.to_owned(), opened_valves.clone(), pressure_records, pressure_released + valve_flow_rate_mapping[&pos] * (mins_left-1), valves_connection_mapping, valve_flow_rate_mapping, num_valves_with_flow);
133+
for e_neighbor in &valves_connection_mapping[&epos] {
134+
dfs_2(best_records, mins_left - 1, neighbor.to_owned(), e_neighbor.to_owned(), opened_valves.clone(), pressure_records, pressure_released, valves_connection_mapping, valve_flow_rate_mapping, num_valves_with_flow);
135+
}
65136
}
66-
}
67137

68-
pub fn part_1(valves_connection_mapping: &HashMap<String, Vec<String>>, valve_flow_rate_mapping: &HashMap<String, usize>) -> usize {
138+
// if only one choose to open valves
139+
let mut pos_opened_just_now = false;
140+
if valve_flow_rate_mapping[&pos] != 0 && !opened_valves.contains(&pos) {
141+
let mut opened_valves_clone = opened_valves.clone();
142+
opened_valves_clone.insert(pos.clone());
143+
pos_opened_just_now = true;
144+
for e_neighbor in &valves_connection_mapping[&epos] {
145+
dfs_2(best_records, mins_left - 1, pos.to_owned(), e_neighbor.to_owned(), opened_valves_clone.clone(), pressure_records,pressure_released + valve_flow_rate_mapping[&pos] * (mins_left-1), valves_connection_mapping, valve_flow_rate_mapping, num_valves_with_flow);
146+
}
147+
}
148+
let mut epos_opened_just_now = false;
149+
if valve_flow_rate_mapping[&epos] != 0 && !opened_valves.contains(&epos) {
150+
let mut opened_valves_clone = opened_valves.clone();
151+
opened_valves_clone.insert(epos.clone());
152+
epos_opened_just_now = true;
153+
for neighbor in &valves_connection_mapping[&pos] {
154+
dfs_2(best_records, mins_left - 1, neighbor.to_owned(), epos.to_owned(), opened_valves_clone.clone(), pressure_records,pressure_released + valve_flow_rate_mapping[&epos] * (mins_left-1), valves_connection_mapping, valve_flow_rate_mapping, num_valves_with_flow);
155+
}
156+
}
157+
// if both choose to open valves
158+
if pos != epos && pos_opened_just_now && epos_opened_just_now {
159+
opened_valves.insert(epos.clone());
160+
opened_valves.insert(pos.clone());
161+
dfs_2(best_records, mins_left - 1, pos.to_owned(), epos.clone(), opened_valves.clone(), pressure_records, pressure_released + valve_flow_rate_mapping[&pos] * (mins_left-1) + valve_flow_rate_mapping[&epos] * (mins_left-1), valves_connection_mapping, valve_flow_rate_mapping, num_valves_with_flow);
162+
}
163+
}
164+
165+
pub fn part_2(valves_connection_mapping: &HashMap<String, Vec<String>>, valve_flow_rate_mapping: &HashMap<String, usize>) -> usize {
69166
let num_valves_with_flow = valve_flow_rate_mapping
70167
.values()
71168
.map(|x| {
@@ -79,9 +176,6 @@ pub fn part_1(valves_connection_mapping: &HashMap<String, Vec<String>>, valve_fl
79176
.sum();
80177
let mut pressure_records = vec![];
81178
let mut best_records = HashMap::new();
82-
dfs(&mut best_records, MINUTES, "AA".to_owned(), HashSet::new(), &mut pressure_records, 0, valves_connection_mapping, valve_flow_rate_mapping, num_valves_with_flow);
179+
dfs_2(&mut best_records, MINUTES-4, "AA".to_owned(), "AA".to_owned(),HashSet::new(), &mut pressure_records, 0, valves_connection_mapping, valve_flow_rate_mapping, num_valves_with_flow);
83180
pressure_records.into_iter().max().unwrap()
84-
}
85-
pub fn part_2(valves_connection_mapping: HashMap<String, Vec<String>>, valve_flow_rate_mapping: HashMap<String, usize>) -> usize {
86-
0
87-
}
181+
}

0 commit comments

Comments
 (0)