[CLEANUP] Cleaned up day 16

This commit is contained in:
2023-01-29 21:36:26 +01:00
parent 9c2793324a
commit f9930694ec

View File

@@ -7,7 +7,7 @@ use super::util;
pub struct Day16 { pub struct Day16 {
valves: Vec<Valve>, valves: Vec<Valve>,
initial_valve_idx: usize, initial_valve_idx: usize,
valve_names: Vec<String> // valve_names: Vec<String>
} }
impl Day16 { impl Day16 {
@@ -18,23 +18,24 @@ impl Day16 {
// We first map all the valve names to indexes for performance reasons: // We first map all the valve names to indexes for performance reasons:
let valve_names = lines.iter() let valve_names = lines.iter()
.map(|s| s.split_whitespace().skip(1).next().unwrap().to_string()) .map(|s| s.split_whitespace().nth(1).unwrap().to_string())
.collect::<Vec<String>>(); .collect::<Vec<String>>();
// Put the input into the day struct // Put the input into the day struct
return Day16 { return Day16 {
valves: lines.iter().enumerate().map(|(i, s)| { valves: lines.iter().enumerate().map(|(_, s)| {
let mut s_split = s.split(";"); let mut s_split = s.split(';');
let flow_rate = s_split.next().unwrap().split("rate=").skip(1).next().unwrap().parse::<u32>().unwrap(); let flow_rate = s_split.next().unwrap().split("rate=").nth(1).unwrap().parse::<u32>().unwrap();
let connections = (&s_split.next().unwrap()["tunnels lead to valves ".len()..].trim()).split(", ") let connections = s_split.next().unwrap()["tunnels lead to valves ".len()..].trim().split(", ")
.map(|n| valve_names.iter().position(|nn| n.eq(nn)).unwrap()) .map(|n| valve_names.iter().position(|nn| n.eq(nn)).unwrap())
.collect(); .collect();
Valve { Valve {
id: i, flow_rate, connections // id: i,
flow_rate, connections
} }
}).collect(), }).collect(),
initial_valve_idx: valve_names.iter().position(|n| n == "AA").unwrap(), initial_valve_idx: valve_names.iter().position(|n| n == "AA").unwrap(),
valve_names // valve_names
} }
} }
@@ -46,19 +47,19 @@ impl Day16 {
open_valves_mask & (1u64 << valve_idx) != 0 open_valves_mask & (1u64 << valve_idx) != 0
} }
fn is_closed(valve_idx: &usize, open_valves_mask: &u64) -> bool { // fn is_closed(valve_idx: &usize, open_valves_mask: &u64) -> bool {
!Self::is_open(valve_idx, open_valves_mask) // !Self::is_open(valve_idx, open_valves_mask)
} // }
//
fn calc_flow_rate(&self, open_valves_mask: &u64) -> u32 { // fn calc_flow_rate(&self, open_valves_mask: &u64) -> u32 {
let mut res = 0; // let mut res = 0;
for i in 0..self.valves.len() { // for i in 0..self.valves.len() {
if Self::is_open(&i, open_valves_mask) { // if Self::is_open(&i, open_valves_mask) {
res += self.valves[i].flow_rate // res += self.valves[i].flow_rate
} // }
} // }
res // res
} // }
fn should_valve_be_opened(&self, valve_idx: &usize, open_valves_mask: &u64) -> bool { fn should_valve_be_opened(&self, valve_idx: &usize, open_valves_mask: &u64) -> bool {
if Self::is_open(valve_idx, open_valves_mask) { false } if Self::is_open(valve_idx, open_valves_mask) { false }
@@ -107,8 +108,8 @@ impl Day16 {
// Now we try all combinations of my and elephants options: // Now we try all combinations of my and elephants options:
let mut best: u32 = 0; let mut best: u32 = 0;
let mut my_best_step = None; // let mut my_best_step = None;
let mut elephant_best_step = None; // let mut elephant_best_step = None;
let next_minutes_left = valve_state.minutes_left - 1; let next_minutes_left = valve_state.minutes_left - 1;
for my_option in my_options { for my_option in my_options {
@@ -122,7 +123,6 @@ impl Day16 {
next_valve_mask_for_me = Self::set_open(&idx, &next_valve_mask_for_me); next_valve_mask_for_me = Self::set_open(&idx, &next_valve_mask_for_me);
next_flow_rate_for_me += self.valves[idx].flow_rate next_flow_rate_for_me += self.valves[idx].flow_rate
} }
_ => {}
} }
for elephant_option in &elephant_options { for elephant_option in &elephant_options {
@@ -133,17 +133,16 @@ impl Day16 {
match elephant_option { match elephant_option {
MoveTo(idx) => elephant_next_position = *idx, MoveTo(idx) => elephant_next_position = *idx,
OpenValve(idx) => { OpenValve(idx) => {
next_valve_mask = Self::set_open(&idx, &next_valve_mask); next_valve_mask = Self::set_open(idx, &next_valve_mask);
next_flow_rate += self.valves[*idx].flow_rate next_flow_rate += self.valves[*idx].flow_rate
} }
_ => {}
} }
let res = self.find_best_option_pt2(ValveStatePt2::new(my_next_position, elephant_next_position, next_valve_mask, next_minutes_left), next_flow_rate, cache); let res = self.find_best_option_pt2(ValveStatePt2::new(my_next_position, elephant_next_position, next_valve_mask, next_minutes_left), next_flow_rate, cache);
if best == 0 || res.total_flow > best { if best == 0 || res.total_flow > best {
best = res.total_flow; best = res.total_flow;
my_best_step = Some(my_option); // my_best_step = Some(my_option);
elephant_best_step = Some(elephant_option.to_owned()); // elephant_best_step = Some(elephant_option.to_owned());
} }
} }
} }
@@ -173,14 +172,14 @@ impl Day16 {
// One option is to open the valve at the current position // One option is to open the valve at the current position
let new_open_valves_mask = Self::set_open(&valve_state.my_position, &valve_state.open_valves_mask); let new_open_valves_mask = Self::set_open(&valve_state.my_position, &valve_state.open_valves_mask);
best_step_result_option = self.find_best_option(ValveState::new(valve_state.my_position, new_open_valves_mask, valve_state.minutes_left - 1), cur_flow_rate + cur_valve.flow_rate, cache); best_step_result_option = self.find_best_option(ValveState::new(valve_state.my_position, new_open_valves_mask, valve_state.minutes_left - 1), cur_flow_rate + cur_valve.flow_rate, cache);
best_step_option = Some(ValveStep::OpenValve(valve_state.my_position)); best_step_option = Some(OpenValve(valve_state.my_position));
} }
// We try and move to an adjacent valve, see if we can be more useful there // We try and move to an adjacent valve, see if we can be more useful there
for connection in cur_valve.connections.iter().rev() { for connection in cur_valve.connections.iter().rev() {
let next_step_result = self.find_best_option(ValveState::new(connection.to_owned(), valve_state.open_valves_mask, valve_state.minutes_left - 1), cur_flow_rate, cache); let next_step_result = self.find_best_option(ValveState::new(connection.to_owned(), valve_state.open_valves_mask, valve_state.minutes_left - 1), cur_flow_rate, cache);
if best_step_result_option.is_none() || next_step_result.as_ref().unwrap().total_flow > best_step_result_option.as_ref().unwrap().total_flow { if best_step_result_option.is_none() || next_step_result.as_ref().unwrap().total_flow > best_step_result_option.as_ref().unwrap().total_flow {
best_step_result_option = next_step_result; best_step_result_option = next_step_result;
best_step_option = Some(ValveStep::MoveTo(connection.to_owned())); best_step_option = Some(MoveTo(connection.to_owned()));
} }
} }
@@ -242,13 +241,13 @@ impl DaySolver for Day16 {
let mut cache= HashMap::new(); let mut cache= HashMap::new();
let best = self.find_best_option_pt2(ValveStatePt2::new(self.initial_valve_idx, self.initial_valve_idx, 0, 26), 0, &mut cache); let best = self.find_best_option_pt2(ValveStatePt2::new(self.initial_valve_idx, self.initial_valve_idx, 0, 26), 0, &mut cache);
return best.total_flow.to_string(); best.total_flow.to_string()
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct Valve { struct Valve {
id: usize, // id: usize,
flow_rate: u32, flow_rate: u32,
connections: Vec<usize> connections: Vec<usize>
} }
@@ -299,5 +298,4 @@ struct BestOptionResult {
enum ValveStep { enum ValveStep {
OpenValve(usize), OpenValve(usize),
MoveTo(usize), MoveTo(usize),
None
} }