d16p1
This commit is contained in:
		
							
								
								
									
										7
									
								
								day16/Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								day16/Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -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" | ||||||
							
								
								
									
										8
									
								
								day16/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								day16/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -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] | ||||||
							
								
								
									
										52
									
								
								day16/input.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								day16/input.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
							
								
								
									
										103
									
								
								day16/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								day16/src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -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<T: FromStr>(str: &str) -> Result<(T, usize), <T as FromStr>::Err> { | ||||||
|  |     let mut iter = str.chars().peekable(); | ||||||
|  |     let mut prefix = String::new(); | ||||||
|  |  | ||||||
|  |     while let Some(c) = iter.peek()  { | ||||||
|  |         if !c.to_string().parse::<T>().is_ok() { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         prefix.push(iter.next().unwrap()); | ||||||
|  |     } | ||||||
|  |     Ok((prefix.parse::<T>()?, prefix.len())) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[derive(Debug)] | ||||||
|  | struct Valve { | ||||||
|  |     rate: u64, | ||||||
|  |     links: Vec<(String, u64)>, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fn read_input(fname: &String) -> Result<HashMap<String, Valve>, <u64 as FromStr>::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::<u64>(&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<String, Valve>) -> 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); | ||||||
|  | } | ||||||
							
								
								
									
										10
									
								
								day16/test.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								day16/test.txt
									
									
									
									
									
										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 | ||||||
		Reference in New Issue
	
	Block a user