From a194cb2d6cfbaf2ae0dcbefee699a9ca7ebbb29c Mon Sep 17 00:00:00 2001 From: Dory Date: Sat, 30 Mar 2024 10:49:01 -0700 Subject: [PATCH] d16p1 --- day16/Cargo.lock | 7 ++++ day16/Cargo.toml | 8 ++++ day16/input.txt | 52 +++++++++++++++++++++++ day16/src/main.rs | 103 ++++++++++++++++++++++++++++++++++++++++++++++ day16/test.txt | 10 +++++ 5 files changed, 180 insertions(+) create mode 100644 day16/Cargo.lock create mode 100644 day16/Cargo.toml create mode 100644 day16/input.txt create mode 100644 day16/src/main.rs create mode 100644 day16/test.txt diff --git a/day16/Cargo.lock b/day16/Cargo.lock new file mode 100644 index 0000000..e3ac8f7 --- /dev/null +++ b/day16/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "day16" +version = "0.1.0" diff --git a/day16/Cargo.toml b/day16/Cargo.toml new file mode 100644 index 0000000..597b6da --- /dev/null +++ b/day16/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day16" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/day16/input.txt b/day16/input.txt new file mode 100644 index 0000000..c4760e8 --- /dev/null +++ b/day16/input.txt @@ -0,0 +1,52 @@ +Valve AP has flow rate=0; tunnels lead to valves AA, ON +Valve QN has flow rate=21; tunnels lead to valves RI, CG +Valve LK has flow rate=0; tunnels lead to valves XM, AA +Valve HA has flow rate=0; tunnels lead to valves WH, KF +Valve DS has flow rate=16; tunnel leads to valve II +Valve KD has flow rate=0; tunnels lead to valves KG, QB +Valve JW has flow rate=0; tunnels lead to valves AD, KF +Valve HU has flow rate=0; tunnels lead to valves UK, CO +Valve AE has flow rate=10; tunnels lead to valves IR, PT, UV +Valve XA has flow rate=0; tunnels lead to valves CG, EU +Valve SE has flow rate=17; tunnels lead to valves YR, AD +Valve TR has flow rate=0; tunnels lead to valves AL, CS +Valve BS has flow rate=0; tunnels lead to valves YH, XM +Valve IJ has flow rate=24; tunnels lead to valves XN, WE +Valve AA has flow rate=0; tunnels lead to valves LK, AP, IZ, PC, QD +Valve KG has flow rate=0; tunnels lead to valves KD, CS +Valve QV has flow rate=0; tunnels lead to valves XM, II +Valve PC has flow rate=0; tunnels lead to valves AA, YF +Valve GJ has flow rate=20; tunnel leads to valve RI +Valve UV has flow rate=0; tunnels lead to valves UK, AE +Valve IR has flow rate=0; tunnels lead to valves EU, AE +Valve EU has flow rate=13; tunnels lead to valves IR, DT, XA, ON +Valve ED has flow rate=0; tunnels lead to valves XN, CO +Valve DT has flow rate=0; tunnels lead to valves EU, UK +Valve YE has flow rate=0; tunnels lead to valves XM, WS +Valve AD has flow rate=0; tunnels lead to valves JW, SE +Valve WE has flow rate=0; tunnels lead to valves IJ, NA +Valve UK has flow rate=5; tunnels lead to valves UV, DT, QD, HU +Valve YR has flow rate=0; tunnels lead to valves OS, SE +Valve II has flow rate=0; tunnels lead to valves QV, DS +Valve GT has flow rate=0; tunnels lead to valves CS, MN +Valve YH has flow rate=0; tunnels lead to valves BS, QB +Valve BQ has flow rate=0; tunnels lead to valves XM, KF +Valve OS has flow rate=0; tunnels lead to valves YR, NA +Valve WH has flow rate=0; tunnels lead to valves QB, HA +Valve QB has flow rate=4; tunnels lead to valves WH, KD, YH, IZ +Valve ON has flow rate=0; tunnels lead to valves AP, EU +Valve IZ has flow rate=0; tunnels lead to valves AA, QB +Valve MN has flow rate=25; tunnel leads to valve GT +Valve CG has flow rate=0; tunnels lead to valves XA, QN +Valve QD has flow rate=0; tunnels lead to valves UK, AA +Valve AL has flow rate=0; tunnels lead to valves KF, TR +Valve XN has flow rate=0; tunnels lead to valves ED, IJ +Valve WS has flow rate=0; tunnels lead to valves YE, CS +Valve CO has flow rate=18; tunnels lead to valves ED, PT, HU +Valve PT has flow rate=0; tunnels lead to valves CO, AE +Valve RI has flow rate=0; tunnels lead to valves QN, GJ +Valve CS has flow rate=9; tunnels lead to valves YF, GT, WS, TR, KG +Valve YF has flow rate=0; tunnels lead to valves PC, CS +Valve NA has flow rate=23; tunnels lead to valves OS, WE +Valve KF has flow rate=12; tunnels lead to valves HA, AL, JW, BQ +Valve XM has flow rate=3; tunnels lead to valves LK, QV, YE, BS, BQ diff --git a/day16/src/main.rs b/day16/src/main.rs new file mode 100644 index 0000000..17b2a27 --- /dev/null +++ b/day16/src/main.rs @@ -0,0 +1,103 @@ +use std::env; +use std::fs::File; +use std::io::{BufReader, BufRead}; +use std::collections::{HashMap, HashSet, VecDeque}; +use std::cmp::max; +use std::str::FromStr; + +fn parse_str(str: &str) -> Result<(T, usize), ::Err> { + let mut iter = str.chars().peekable(); + let mut prefix = String::new(); + + while let Some(c) = iter.peek() { + if !c.to_string().parse::().is_ok() { + break; + } + prefix.push(iter.next().unwrap()); + } + Ok((prefix.parse::()?, prefix.len())) +} + +#[derive(Debug)] +struct Valve { + rate: u64, + links: Vec<(String, u64)>, +} + +fn read_input(fname: &String) -> Result, ::Err> { + let file = File::open(fname).expect("cannot open input file"); + let lines = BufReader::new(file).lines(); + let mut valves = HashMap::new(); + for line in lines.flatten() { + let name = String::from(&line[6..=7]); + let (rate, rate_len) = parse_str::(&line[23..])?; + let links_str = &line[23 + rate_len + 24..]; + let mut link = String::new(); + let mut links = Vec::new(); + let mut iter = links_str.chars(); + loop { + match iter.next() { + Some(' ') | Some(',') => continue, + None => break, + Some(c) => { + link.push(c); + link.push(iter.next().unwrap()); + links.push((link.clone(), 1)); + link = String::new(); + }, + } + } + valves.insert(name, Valve { rate, links }); + } + Ok(valves) +} + +fn routes_from(valve: &String, valves: &HashMap) -> Valve { + let mut visited = HashSet::from([valve.clone()]); + let mut queue = VecDeque::from([(valve.clone(), 0)]); + let mut links = Vec::new(); + while !queue.is_empty() { + let (current_valve, current_cost) = queue.pop_front().unwrap(); + if current_valve != *valve && valves[¤t_valve].rate > 0 { + // +1 because it takes 1min to open a valve + links.push((current_valve.clone(), current_cost + 1)); + } + for (next_valve, _) in &valves[¤t_valve].links { + if !visited.contains(next_valve) { + queue.push_back((next_valve.clone(), current_cost + 1)); + visited.insert(next_valve.clone()); + } + } + } + Valve { rate: valves[valve].rate, links: links } +} + +fn main() { + let input_fname = env::args().nth(1).expect("need input file"); + let valves = read_input(&input_fname).expect("parse error"); + let mut good_valves = HashMap::new(); + for (valve_name, valve) in &valves { + if valve.rate > 0 || valve_name == "AA" { + good_valves.insert(valve_name, routes_from(valve_name, &valves)); + } + } + + let mut max_pressure = 0; + let mut queue: VecDeque<(String, u64, u64, HashSet<_>)> = VecDeque::from([( + String::from("AA"), 0, 0, HashSet::from([String::from("AA")]))]); + while !queue.is_empty() { + let (valve, cost, pressure, visited) = queue.pop_front().unwrap(); + max_pressure = max(max_pressure, pressure); + for (hop, hop_cost) in &good_valves[&valve].links { + if cost + hop_cost >= 30 || visited.contains(hop) { + continue; + } + let new_cost = cost + hop_cost; + let new_pressure = pressure + (30 - new_cost)*valves[hop].rate; + let mut new_visited = visited.clone(); + new_visited.insert(hop.clone()); + queue.push_back((hop.clone(), new_cost, new_pressure, new_visited)); + } + } + println!("Max pressure: {}", max_pressure); +} diff --git a/day16/test.txt b/day16/test.txt new file mode 100644 index 0000000..9f30acc --- /dev/null +++ b/day16/test.txt @@ -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