[rs] Solve 2022_16 part 1
This commit is contained in:
parent
cc8fe30a36
commit
a794e21840
7 changed files with 194 additions and 0 deletions
51
inputs/2022/2022_16.input
Normal file
51
inputs/2022/2022_16.input
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
Valve NV has flow rate=5; tunnels lead to valves ZV, CG, YB, HX, OY
|
||||
Valve NU has flow rate=6; tunnels lead to valves DA, MA, OA, DK
|
||||
Valve VU has flow rate=0; tunnels lead to valves PS, FX
|
||||
Valve JW has flow rate=0; tunnels lead to valves AA, MD
|
||||
Valve RI has flow rate=0; tunnels lead to valves OY, DG
|
||||
Valve DG has flow rate=9; tunnels lead to valves TG, RI, DF, EV, KW
|
||||
Valve PH has flow rate=7; tunnels lead to valves KW, OW, LT, LZ
|
||||
Valve KZ has flow rate=12; tunnels lead to valves ET, QV, CK, MS
|
||||
Valve IX has flow rate=0; tunnels lead to valves TS, DO
|
||||
Valve MS has flow rate=0; tunnels lead to valves LZ, KZ
|
||||
Valve IL has flow rate=0; tunnels lead to valves DO, ET
|
||||
Valve EJ has flow rate=20; tunnels lead to valves AV, JY
|
||||
Valve DK has flow rate=0; tunnels lead to valves NU, CG
|
||||
Valve YB has flow rate=0; tunnels lead to valves NV, PS
|
||||
Valve OA has flow rate=0; tunnels lead to valves YA, NU
|
||||
Valve DA has flow rate=0; tunnels lead to valves NU, RG
|
||||
Valve KO has flow rate=0; tunnels lead to valves AA, TG
|
||||
Valve RG has flow rate=4; tunnels lead to valves DF, DA, ZV, MD, LB
|
||||
Valve MA has flow rate=0; tunnels lead to valves AA, NU
|
||||
Valve OW has flow rate=0; tunnels lead to valves DO, PH
|
||||
Valve KW has flow rate=0; tunnels lead to valves DG, PH
|
||||
Valve DO has flow rate=14; tunnels lead to valves IX, IL, CZ, OW
|
||||
Valve DF has flow rate=0; tunnels lead to valves RG, DG
|
||||
Valve TG has flow rate=0; tunnels lead to valves DG, KO
|
||||
Valve LB has flow rate=0; tunnels lead to valves RG, FX
|
||||
Valve HX has flow rate=0; tunnels lead to valves AA, NV
|
||||
Valve GB has flow rate=0; tunnels lead to valves AV, XK
|
||||
Valve CG has flow rate=0; tunnels lead to valves DK, NV
|
||||
Valve LT has flow rate=0; tunnels lead to valves AO, PH
|
||||
Valve FX has flow rate=23; tunnels lead to valves LB, HY, VU
|
||||
Valve ET has flow rate=0; tunnels lead to valves IL, KZ
|
||||
Valve CK has flow rate=0; tunnels lead to valves UX, KZ
|
||||
Valve LZ has flow rate=0; tunnels lead to valves PH, MS
|
||||
Valve YA has flow rate=17; tunnels lead to valves JY, OA
|
||||
Valve TS has flow rate=0; tunnels lead to valves NO, IX
|
||||
Valve NO has flow rate=8; tunnel leads to valve TS
|
||||
Valve XK has flow rate=24; tunnel leads to valve GB
|
||||
Valve PS has flow rate=18; tunnels lead to valves EV, VU, YB
|
||||
Valve AA has flow rate=0; tunnels lead to valves JW, HX, MA, KO
|
||||
Valve MD has flow rate=0; tunnels lead to valves JW, RG
|
||||
Valve JM has flow rate=19; tunnels lead to valves QV, HY, AO
|
||||
Valve AV has flow rate=0; tunnels lead to valves EJ, GB
|
||||
Valve AO has flow rate=0; tunnels lead to valves JM, LT
|
||||
Valve JY has flow rate=0; tunnels lead to valves YA, EJ
|
||||
Valve OY has flow rate=0; tunnels lead to valves NV, RI
|
||||
Valve UX has flow rate=13; tunnels lead to valves CZ, CK
|
||||
Valve HY has flow rate=0; tunnels lead to valves JM, FX
|
||||
Valve EV has flow rate=0; tunnels lead to valves PS, DG
|
||||
Valve CZ has flow rate=0; tunnels lead to valves UX, DO
|
||||
Valve ZV has flow rate=0; tunnels lead to valves NV, RG
|
||||
Valve QV has flow rate=0; tunnels lead to valves JM, KZ
|
||||
2
inputs/2022/2022_16.solution
Normal file
2
inputs/2022/2022_16.solution
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Part 1: 1923
|
||||
Part 2: ???
|
||||
|
|
@ -66,6 +66,7 @@ days! {
|
|||
Y2022D13: "2022_13" => y2022::d13::solve,
|
||||
Y2022D14: "2022_14" => y2022::d14::solve,
|
||||
Y2022D15: "2022_15" => y2022::d15::solve,
|
||||
Y2022D16: "2022_16" => y2022::d16::solve,
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
|
|
|
|||
|
|
@ -13,3 +13,4 @@ pub mod d12;
|
|||
pub mod d13;
|
||||
pub mod d14;
|
||||
pub mod d15;
|
||||
pub mod d16;
|
||||
|
|
|
|||
127
rs/src/y2022/d16.rs
Normal file
127
rs/src/y2022/d16.rs
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
fn parse_valve(line: &str) -> (&str, u32, Vec<&str>) {
|
||||
let (name, rest) = line
|
||||
.strip_prefix("Valve ")
|
||||
.unwrap()
|
||||
.split_once(" has flow rate=")
|
||||
.unwrap();
|
||||
let (rate, rest) = rest.split_once("; ").unwrap();
|
||||
let next = rest
|
||||
.strip_prefix("tunnel leads to valve ")
|
||||
.or_else(|| rest.strip_prefix("tunnels lead to valves "))
|
||||
.unwrap()
|
||||
.split(", ")
|
||||
.collect::<Vec<_>>();
|
||||
(name, rate.parse().unwrap(), next)
|
||||
}
|
||||
#[derive(Debug)]
|
||||
struct Valve {
|
||||
rate: u32,
|
||||
next: Vec<usize>,
|
||||
}
|
||||
|
||||
fn prepare_valves<'a>(
|
||||
mut valves: Vec<(&'a str, u32, Vec<&str>)>,
|
||||
) -> (HashMap<&'a str, usize>, Vec<Valve>) {
|
||||
// All valves with a nonzero rate should come before the ones with a rate of
|
||||
// zero. This will help with our valve bitset later.
|
||||
valves.sort_by_key(|(_, rate, _)| *rate);
|
||||
valves.reverse();
|
||||
|
||||
let names = valves
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, (n, _, _))| (*n, i))
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
let valves = valves
|
||||
.into_iter()
|
||||
.map(|(_, rate, next)| {
|
||||
let next = next.into_iter().map(|n| names[n]).collect();
|
||||
Valve { rate, next }
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
(names, valves)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
struct OpenSet(u64);
|
||||
|
||||
impl OpenSet {
|
||||
const ALL_CLOSED: Self = Self(0);
|
||||
|
||||
/// The powerset of the set of all open valves.
|
||||
fn powerset(valves: &[Valve]) -> Vec<Self> {
|
||||
assert!(valves.len() <= 63);
|
||||
let first_zero_rate = valves
|
||||
.iter()
|
||||
.position(|v| v.rate == 0)
|
||||
.unwrap_or(valves.len());
|
||||
let until = 2_u64.pow(first_zero_rate as u32);
|
||||
(0..until).map(Self).collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
fn is_open(&self, valve_id: usize) -> bool {
|
||||
assert!(valve_id < 63);
|
||||
self.0 & (1 << valve_id) != 0
|
||||
}
|
||||
|
||||
fn open(&self, valve_id: usize) -> Self {
|
||||
assert!(valve_id < 63);
|
||||
Self(self.0 | (1 << valve_id))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn solve(input: String) {
|
||||
let valves = input.lines().map(parse_valve).collect::<Vec<_>>();
|
||||
|
||||
let (names, valves) = prepare_valves(valves);
|
||||
let powerset = OpenSet::powerset(&valves);
|
||||
eprintln!("Powerset has size {}", powerset.len());
|
||||
|
||||
// DP state consists of:
|
||||
// - The current minute
|
||||
// - The current valve
|
||||
// - The current set of open/closed valves
|
||||
|
||||
let mut dp = HashMap::new();
|
||||
|
||||
// Initialize for end state
|
||||
eprintln!("Minute 0");
|
||||
for valve_id in 0..valves.len() {
|
||||
for open in &powerset {
|
||||
dp.insert((0_u32, valve_id, *open), 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Given valve v in minute t with set s, you can either...
|
||||
// - Go to another neighbouring valve v', points: points[v', t-1, s]
|
||||
// - If v not in s: Open current valve, points: points[v, t-1, s+{v}] + t
|
||||
|
||||
for minute in 1..=30 {
|
||||
eprintln!("Minute {minute}");
|
||||
for (valve_id, valve) in valves.iter().enumerate() {
|
||||
for open in &powerset {
|
||||
let mut score = valve
|
||||
.next
|
||||
.iter()
|
||||
.map(|next_id| dp[&(minute - 1, *next_id, *open)])
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
|
||||
if valve.rate > 0 && !open.is_open(valve_id) {
|
||||
let room_but_valve_open = dp[&(minute - 1, valve_id, open.open(valve_id))];
|
||||
let pressure_until_end = (minute - 1) * valve.rate;
|
||||
score = score.max(room_but_valve_open + pressure_until_end);
|
||||
}
|
||||
|
||||
dp.insert((minute, valve_id, *open), score);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let part1 = dp[&(30, names["AA"], OpenSet::ALL_CLOSED)];
|
||||
println!("Part 1: {part1}");
|
||||
}
|
||||
10
sample_inputs/2022/2022_16.input
Normal file
10
sample_inputs/2022/2022_16.input
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
|
||||
Valve BB has flow rate=13; tunnels lead to valves CC, AA
|
||||
Valve CC has flow rate=2; tunnels lead to valves DD, BB
|
||||
Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
|
||||
Valve EE has flow rate=3; tunnels lead to valves FF, DD
|
||||
Valve FF has flow rate=0; tunnels lead to valves EE, GG
|
||||
Valve GG has flow rate=0; tunnels lead to valves FF, HH
|
||||
Valve HH has flow rate=22; tunnel leads to valve GG
|
||||
Valve II has flow rate=0; tunnels lead to valves AA, JJ
|
||||
Valve JJ has flow rate=21; tunnel leads to valve II
|
||||
2
sample_inputs/2022/2022_16.solution
Normal file
2
sample_inputs/2022/2022_16.solution
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Part 1: 1651
|
||||
Part 2: ???
|
||||
Loading…
Add table
Add a link
Reference in a new issue