Skip to content

Commit 29c0fb7

Browse files
committed
feat(2022): refactor day 16
Refactored Day 16 of 2022 to use the common framework. Successfully migrated solution, updated project structure, and integrated it into the runner.
1 parent 967f694 commit 29c0fb7

3 files changed

Lines changed: 181 additions & 0 deletions

File tree

2022/inputs/16/prod.txt

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
Valve WT has flow rate=0; tunnels lead to valves BD, FQ
2+
Valve UG has flow rate=0; tunnels lead to valves FQ, YB
3+
Valve FN has flow rate=0; tunnels lead to valves TV, GA
4+
Valve RU has flow rate=11; tunnels lead to valves YZ, QS, BL, BT, WJ
5+
Valve RH has flow rate=0; tunnels lead to valves AS, II
6+
Valve FL has flow rate=0; tunnels lead to valves HR, PQ
7+
Valve KQ has flow rate=18; tunnels lead to valves FR, BN
8+
Valve PM has flow rate=25; tunnels lead to valves YZ, FR
9+
Valve RQ has flow rate=0; tunnels lead to valves FQ, MW
10+
Valve BL has flow rate=0; tunnels lead to valves RU, IR
11+
Valve FF has flow rate=0; tunnels lead to valves QS, ED
12+
Valve KP has flow rate=0; tunnels lead to valves QM, MA
13+
Valve YB has flow rate=0; tunnels lead to valves UG, HR
14+
Valve TV has flow rate=17; tunnels lead to valves BD, MT, FN
15+
Valve HY has flow rate=0; tunnels lead to valves DW, IU
16+
Valve KF has flow rate=0; tunnels lead to valves AA, HR
17+
Valve YC has flow rate=0; tunnels lead to valves II, MA
18+
Valve EE has flow rate=0; tunnels lead to valves AA, CD
19+
Valve ED has flow rate=9; tunnels lead to valves HG, FF
20+
Valve SA has flow rate=0; tunnels lead to valves MW, LS
21+
Valve II has flow rate=20; tunnels lead to valves YC, CY, QP, RH
22+
Valve BN has flow rate=0; tunnels lead to valves BT, KQ
23+
Valve MO has flow rate=0; tunnels lead to valves XO, VI
24+
Valve YZ has flow rate=0; tunnels lead to valves RU, PM
25+
Valve WJ has flow rate=0; tunnels lead to valves RU, QP
26+
Valve AW has flow rate=0; tunnels lead to valves HR, DW
27+
Valve MJ has flow rate=0; tunnels lead to valves BP, AA
28+
Valve DW has flow rate=4; tunnels lead to valves AU, CB, HY, GL, AW
29+
Valve QM has flow rate=0; tunnels lead to valves KP, FQ
30+
Valve LF has flow rate=5; tunnels lead to valves LS, QN, AU, BP, ZY
31+
Valve QS has flow rate=0; tunnels lead to valves FF, RU
32+
Valve BT has flow rate=0; tunnels lead to valves BN, RU
33+
Valve VI has flow rate=22; tunnel leads to valve MO
34+
Valve LS has flow rate=0; tunnels lead to valves LF, SA
35+
Valve QD has flow rate=0; tunnels lead to valves HR, ZY
36+
Valve HG has flow rate=0; tunnels lead to valves AS, ED
37+
Valve BD has flow rate=0; tunnels lead to valves WT, TV
38+
Valve CD has flow rate=0; tunnels lead to valves EE, MW
39+
Valve QP has flow rate=0; tunnels lead to valves II, WJ
40+
Valve MW has flow rate=7; tunnels lead to valves PQ, SA, CB, CD, RQ
41+
Valve AU has flow rate=0; tunnels lead to valves DW, LF
42+
Valve RR has flow rate=0; tunnels lead to valves AS, MA
43+
Valve GA has flow rate=0; tunnels lead to valves FN, MA
44+
Valve MT has flow rate=0; tunnels lead to valves CY, TV
45+
Valve HR has flow rate=14; tunnels lead to valves KF, YB, QD, AW, FL
46+
Valve AS has flow rate=16; tunnels lead to valves RR, RH, HG, IR
47+
Valve CY has flow rate=0; tunnels lead to valves MT, II
48+
Valve AA has flow rate=0; tunnels lead to valves OX, KF, GL, MJ, EE
49+
Valve IU has flow rate=0; tunnels lead to valves XO, HY
50+
Valve XO has flow rate=23; tunnels lead to valves IU, MO
51+
Valve FR has flow rate=0; tunnels lead to valves KQ, PM
52+
Valve CB has flow rate=0; tunnels lead to valves MW, DW
53+
Valve ZY has flow rate=0; tunnels lead to valves QD, LF
54+
Valve BP has flow rate=0; tunnels lead to valves LF, MJ
55+
Valve QN has flow rate=0; tunnels lead to valves LF, FQ
56+
Valve IR has flow rate=0; tunnels lead to valves AS, BL
57+
Valve PQ has flow rate=0; tunnels lead to valves FL, MW
58+
Valve GL has flow rate=0; tunnels lead to valves AA, DW
59+
Valve OX has flow rate=0; tunnels lead to valves MA, AA
60+
Valve MA has flow rate=10; tunnels lead to valves RR, YC, GA, OX, KP
61+
Valve FQ has flow rate=12; tunnels lead to valves QN, WT, UG, RQ, QM

2022/inputs/16/test.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
2+
Valve BB has flow rate=13; tunnels lead to valves CC, AA
3+
Valve CC has flow rate=2; tunnels lead to valves DD, BB
4+
Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
5+
Valve EE has flow rate=3; tunnels lead to valves FF, DD
6+
Valve FF has flow rate=0; tunnels lead to valves EE, GG
7+
Valve GG has flow rate=0; tunnels lead to valves FF, HH
8+
Valve HH has flow rate=22; tunnel leads to valve GG
9+
Valve II has flow rate=0; tunnels lead to valves AA, JJ
10+
Valve JJ has flow rate=21; tunnel leads to valve II

2022/src/day16.rs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
use aoc_rust_common::Solution;
2+
use std::fmt::Display;
3+
use std::collections::HashMap;
4+
use sscanf::sscanf;
5+
6+
pub struct Day16;
7+
8+
#[derive(Debug)]
9+
struct Valve<'a> {
10+
name: &'a str,
11+
flow: u16,
12+
tunnels: Vec<&'a str>,
13+
}
14+
15+
impl Solution for Day16 {
16+
fn year(&self) -> u32 { 2022 }
17+
fn day(&self) -> u32 { 16 }
18+
19+
fn part1(&self, input: &str) -> Box<dyn Display> {
20+
let valves = parse(input);
21+
let dists = compute_dists(&valves);
22+
let non_zero = valves.iter().filter(|v| v.flow > 0).map(|v| v.name).collect::<Vec<_>>();
23+
let start = "AA";
24+
25+
let mut memo = HashMap::new();
26+
Box::new(max_pressure(start, 30, 0, &non_zero, &dists, &valves, &mut memo))
27+
}
28+
29+
fn part2(&self, input: &str) -> Box<dyn Display> {
30+
let valves = parse(input);
31+
let dists = compute_dists(&valves);
32+
let non_zero = valves.iter().filter(|v| v.flow > 0).map(|v| v.name).collect::<Vec<_>>();
33+
let start = "AA";
34+
35+
let mut memo = HashMap::new();
36+
Box::new(max_pressure_two(start, start, 26, 26, 0, &non_zero, &dists, &valves, &mut memo))
37+
}
38+
}
39+
40+
fn parse(input: &str) -> Vec<Valve> {
41+
input.lines().map(|line| {
42+
let (name, flow, _, tunnels) = sscanf!(line, "Valve {str} has flow rate={u16}; {str:/tunnels? leads? to valves?/} {str}").unwrap();
43+
Valve { name, flow, tunnels: tunnels.split(", ").collect() }
44+
}).collect()
45+
}
46+
47+
fn compute_dists(valves: &[Valve]) -> HashMap<(&str, &str), u16> {
48+
let mut dists = HashMap::new();
49+
for v in valves {
50+
for t in &v.tunnels {
51+
dists.insert((v.name, *t), 1);
52+
}
53+
dists.insert((v.name, v.name), 0);
54+
}
55+
for k in valves.iter().map(|v| v.name) {
56+
for i in valves.iter().map(|v| v.name) {
57+
for j in valves.iter().map(|v| v.name) {
58+
let d_ij = *dists.get(&(i, j)).unwrap_or(&1000);
59+
let d_ik = *dists.get(&(i, k)).unwrap_or(&1000);
60+
let d_kj = *dists.get(&(k, j)).unwrap_or(&1000);
61+
if d_ik + d_kj < d_ij {
62+
dists.insert((i, j), d_ik + d_kj);
63+
}
64+
}
65+
}
66+
}
67+
dists
68+
}
69+
70+
fn max_pressure<'a>(curr: &'a str, time: u16, opened: u32, non_zero: &[&'a str], dists: &HashMap<(&str, &str), u16>, valves: &[Valve<'a>], memo: &mut HashMap<(&'a str, u16, u32), u16>) -> u16 {
71+
if time == 0 { return 0; }
72+
let key = (curr, time, opened);
73+
if let Some(&res) = memo.get(&key) { return res; }
74+
75+
let mut res = 0;
76+
for (i, &next) in non_zero.iter().enumerate() {
77+
if (opened & (1 << i)) == 0 {
78+
let dist = *dists.get(&(curr, next)).unwrap();
79+
if time > dist + 1 {
80+
let flow = valves.iter().find(|v| v.name == next).unwrap().flow;
81+
res = res.max(flow * (time - dist - 1) + max_pressure(next, time - dist - 1, opened | (1 << i), non_zero, dists, valves, memo));
82+
}
83+
}
84+
}
85+
memo.insert(key, res);
86+
res
87+
}
88+
89+
fn max_pressure_two<'a>(curr1: &'a str, curr2: &'a str, time1: u16, time2: u16, opened: u32, non_zero: &[&'a str], dists: &HashMap<(&str, &str), u16>, valves: &[Valve<'a>], memo: &mut HashMap<(&'a str, &'a str, u16, u16, u32), u16>) -> u16 {
90+
let key = (curr1, curr2, time1, time2, opened);
91+
if let Some(&res) = memo.get(&key) { return res; }
92+
93+
let mut res = 0;
94+
for (i, &next) in non_zero.iter().enumerate() {
95+
if (opened & (1 << i)) == 0 {
96+
let dist1 = *dists.get(&(curr1, next)).unwrap();
97+
if time1 > dist1 + 1 {
98+
let flow = valves.iter().find(|v| v.name == next).unwrap().flow;
99+
res = res.max(flow * (time1 - dist1 - 1) + max_pressure_two(next, curr2, time1 - dist1 - 1, time2, opened | (1 << i), non_zero, dists, valves, memo));
100+
}
101+
let dist2 = *dists.get(&(curr2, next)).unwrap();
102+
if time2 > dist2 + 1 {
103+
let flow = valves.iter().find(|v| v.name == next).unwrap().flow;
104+
res = res.max(flow * (time2 - dist2 - 1) + max_pressure_two(curr1, next, time1, time2 - dist2 - 1, opened | (1 << i), non_zero, dists, valves, memo));
105+
}
106+
}
107+
}
108+
memo.insert(key, res);
109+
res
110+
}

0 commit comments

Comments
 (0)