diff --git a/src/days/d16.rs b/src/days/d16.rs index e6aea09..9696bad 100644 --- a/src/days/d16.rs +++ b/src/days/d16.rs @@ -6,26 +6,77 @@ pub fn solve() { let contents = fs::read_to_string(path).expect("File read error"); - let mut valves = HashMap::)>::new(); + // maps valve name to list of adjacents with (name, flow rate (of this valve), minutes) + let mut valves = Vec::<(&str, i32, Vec<&str>)>::new(); contents .lines() .filter(|line| *line != "") .for_each(|line| { let (valve, conn_valves) = line.split_at(line.find(";").unwrap()); - let conn_valves = conn_valves + let conn_valves2 = conn_valves .replace("; tunnels lead to valve", "") .replace("s", "") .replace(" ", ""); - let conn_valves: Vec<&str> = conn_valves.split(",").collect(); - let conn_valves: Vec = conn_valves.iter().map(|c| c.to_string()).collect(); + let conn_valves3: Vec<&str> = conn_valves2.split(",").collect(); let valve: Vec<&str> = valve.split_whitespace().collect(); let flow_rate = valve[4].replace("rate=", "").parse::().unwrap(); - let valve = valve[1].to_string(); - valves.insert(valve, (flow_rate, conn_valves)); + valves.push((valve[1], flow_rate, conn_valves3)); }); dbg!(valves); + + + + // maps valve name to array index + let mut v_id = HashMap::<&str, i32>::new(); + valves + .iter() + .enumerate() + .for_each(|(i, valve)| { v_id.insert(valve.0, i as i32);} ); + + // amount of valves with flow rates > 0 + let v_pos_num = valves + .iter() + .filter(|valve| valve.1 > 0) + .count(); + + + + let v_num = valves.len(); + let v_pos_bits = 1 << v_pos_num; // 2 ^ v_pos_num ? + + let mut valves_by_id = vec![(0, Vec::::new()); v_num]; + valves.iter().for_each(|valve| { + let i = v_id[valve.0]; + valves_by_id[i as usize] = (valve.1, valve.2.iter().map(|adj| v_id[*adj]).collect::>()); + }); + + + let mut dp = vec![vec![vec![0;v_pos_bits];v_num];30]; + + for t in 1..30 { + for i in 0..v_num { + let i_bit = 1 << i; // i'th valve is open + for j in 0..v_pos_bits { + let mut curr = dp[t][i][j]; + if i_bit & j != 0 && t >= 2 { // current j represents state where i'th valve is open + curr = curr.max( + dp[t-1][i][j-i_bit] // value without valve open + + valves_by_id[i].0 * t as i32) // plus valve open at current time + } + valves_by_id[i].1.iter().for_each(|adj| { + curr = curr.max(dp[t-1][*adj as usize][j]); // if larger, come from adjacent + }); + dp[t][i][j] = curr; + } + } + } + + let res = dp[29][*v_id.get(&"AA").unwrap() as usize][v_pos_bits-1]; + println!("Result 1: {res:?}"); + return; + } \ No newline at end of file