Added day 16
This commit is contained in:
parent
6c4faba2f5
commit
ff8732bb80
106
src/day16/1.rs
106
src/day16/1.rs
|
@ -0,0 +1,106 @@
|
|||
#![feature(test)]
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
extern crate test;
|
||||
|
||||
const INPUTS: [&str; 2] = [include_str!("./sample.txt"), include_str!("./input.txt")];
|
||||
|
||||
#[derive(Clone, Debug, Ord, PartialEq, PartialOrd, Eq)]
|
||||
struct Node {
|
||||
flow: i32,
|
||||
idx: usize,
|
||||
leads_to: Vec<String>,
|
||||
}
|
||||
|
||||
fn parse(input: &'static str) -> HashMap<String, Node> {
|
||||
input
|
||||
.lines()
|
||||
.enumerate()
|
||||
.map(|(i, line)| {
|
||||
let mut num = 0;
|
||||
let mut node = "".to_string();
|
||||
let mut children = vec![];
|
||||
for c in line.chars().skip(1).filter(|&c| {
|
||||
('A'..='Z').contains(&c) || ('0'..='9').contains(&c) || c == ',' || c == '='
|
||||
}) {
|
||||
match c {
|
||||
'A'..='Z' => {
|
||||
node.push(c);
|
||||
}
|
||||
'0'..='9' => num = num * 10 + (c as u8 - b'0') as i32,
|
||||
'=' | ',' => {
|
||||
children.push(node.clone());
|
||||
node.clear();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
children.push(node);
|
||||
|
||||
(
|
||||
children[0].clone(),
|
||||
Node {
|
||||
flow: num,
|
||||
idx: i,
|
||||
leads_to: children[1..].to_vec(),
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
const MAX_TIME: i32 = 30;
|
||||
|
||||
fn solution(input: HashMap<String, Node>) -> i32 {
|
||||
let mut choices = HashMap::with_capacity(50);
|
||||
choices.insert((0, "AA".to_string()), (0, 0, 0u128));
|
||||
|
||||
for minute in 0..MAX_TIME {
|
||||
let mut new_choices = HashMap::with_capacity(50);
|
||||
|
||||
for (k, choice) in choices {
|
||||
let new_valve = &k.1;
|
||||
let ip = input.get(new_valve).unwrap();
|
||||
let new_valve_idx = ip.idx;
|
||||
|
||||
let new_time = choice.0 + 1;
|
||||
let mut new_release = choice.1;
|
||||
|
||||
for path in ip.leads_to.iter() {
|
||||
let new_choice = (new_time, new_release, choice.2);
|
||||
|
||||
new_choices.insert((new_release, path.to_string()), new_choice);
|
||||
}
|
||||
|
||||
if ip.flow > 0 && choice.2 & (1 << new_valve_idx) < 1 {
|
||||
new_release += ip.flow * (MAX_TIME - minute - 1);
|
||||
|
||||
let new_choice = (new_time, new_release, choice.2 | (1 << new_valve_idx));
|
||||
|
||||
new_choices.insert((new_release, new_valve.to_string()), new_choice);
|
||||
}
|
||||
}
|
||||
|
||||
choices = new_choices;
|
||||
}
|
||||
|
||||
choices.values().map(|c| c.1).max().unwrap()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
for input in INPUTS.iter() {
|
||||
let output = parse(input);
|
||||
let score = solution(output);
|
||||
println!("{}", score);
|
||||
}
|
||||
}
|
||||
#[bench]
|
||||
fn solution_bench(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
let input = parse(INPUTS[1]);
|
||||
let result = solution(input);
|
||||
test::black_box(result);
|
||||
})
|
||||
}
|
142
src/day16/2.rs
142
src/day16/2.rs
|
@ -0,0 +1,142 @@
|
|||
#![feature(test)]
|
||||
|
||||
use std::{cmp::Ordering, collections::HashMap};
|
||||
extern crate test;
|
||||
|
||||
const INPUTS: [&str; 2] = [include_str!("./sample.txt"), include_str!("./input.txt")];
|
||||
|
||||
#[derive(Clone, Debug, Ord, PartialEq, PartialOrd, Eq)]
|
||||
struct Node {
|
||||
flow: i32,
|
||||
idx: usize,
|
||||
leads_to: Vec<String>,
|
||||
}
|
||||
|
||||
fn parse(input: &'static str) -> HashMap<String, Node> {
|
||||
input
|
||||
.lines()
|
||||
.enumerate()
|
||||
.map(|(i, line)| {
|
||||
let mut num = 0;
|
||||
let mut node = "".to_string();
|
||||
let mut children = vec![];
|
||||
for c in line.chars().skip(1).filter(|&c| {
|
||||
('A'..='Z').contains(&c)
|
||||
|| ('0'..='9').contains(&c)
|
||||
|| c == ','
|
||||
|| c == ';'
|
||||
|| c == '='
|
||||
}) {
|
||||
match c {
|
||||
'A'..='Z' => node.push(c),
|
||||
'0'..='9' => num = num * 10 + (c as u8 - b'0') as i32,
|
||||
'=' | ',' => {
|
||||
children.push(node.clone());
|
||||
node.clear();
|
||||
}
|
||||
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
children.push(node);
|
||||
|
||||
(
|
||||
children[0].clone(),
|
||||
Node {
|
||||
flow: num,
|
||||
idx: i,
|
||||
leads_to: children[1..].to_vec(),
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
const MAX_TIME: i32 = 26;
|
||||
|
||||
fn solution(input: HashMap<String, Node>) -> i32 {
|
||||
let mut new_choices = HashMap::with_capacity(500);
|
||||
let mut choices = HashMap::with_capacity(500);
|
||||
choices.insert((0, "AA".to_string(), "AA".to_string()), (0, 0u128));
|
||||
|
||||
'outer: for minute in 0..MAX_TIME {
|
||||
for (k, choice) in &choices {
|
||||
let mut hpaths = input.get(&k.1).unwrap().leads_to.clone();
|
||||
hpaths.push(k.1.clone());
|
||||
|
||||
let mut epaths = input.get(&k.2).unwrap().leads_to.clone();
|
||||
epaths.push(k.2.clone());
|
||||
|
||||
if choice.1.count_ones() == input.len() as u32 {
|
||||
break 'outer;
|
||||
}
|
||||
|
||||
for h in hpaths {
|
||||
let epaths = epaths.clone();
|
||||
for e in epaths {
|
||||
let new_h_valve = h.clone();
|
||||
let new_h_valve_flow = input.get(&new_h_valve).unwrap().flow;
|
||||
let new_h_valve_idx = input.get(&new_h_valve).unwrap().idx;
|
||||
|
||||
let mut new_release = choice.0;
|
||||
let new_e_valve = e;
|
||||
let new_e_valve_flow = input.get(&new_e_valve).unwrap().flow;
|
||||
let new_e_valve_idx = input.get(&new_e_valve).unwrap().idx;
|
||||
|
||||
let mut new_state = choice.1;
|
||||
|
||||
match (new_e_valve.cmp(&k.2), new_h_valve.cmp(&k.1)) {
|
||||
(Ordering::Equal, Ordering::Equal) => {
|
||||
if (new_state & (1 << new_h_valve_idx) < 1)
|
||||
&& (new_state & (1 << new_e_valve_idx) < 1)
|
||||
{
|
||||
new_release += new_h_valve_flow * (MAX_TIME - minute - 1);
|
||||
new_state |= 1 << new_h_valve_idx;
|
||||
if new_state & (1 << new_e_valve_idx) < 1 {
|
||||
new_release += new_e_valve_flow * (MAX_TIME - minute - 1);
|
||||
new_state |= 1 << new_e_valve_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
(_, Ordering::Equal) if new_state & (1 << new_h_valve_idx) < 1 => {
|
||||
new_release += new_h_valve_flow * (MAX_TIME - minute - 1);
|
||||
new_state |= 1 << new_h_valve_idx;
|
||||
}
|
||||
(Ordering::Equal, _) if new_state & (1 << new_e_valve_idx) < 1 => {
|
||||
new_release += new_e_valve_flow * (MAX_TIME - minute - 1);
|
||||
new_state |= 1 << new_e_valve_idx;
|
||||
}
|
||||
|
||||
(_, _) => (),
|
||||
}
|
||||
|
||||
let new_choice = (new_release, new_state);
|
||||
|
||||
new_choices.insert((new_release, new_h_valve, new_e_valve), new_choice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::mem::swap(&mut choices, &mut new_choices);
|
||||
new_choices.clear();
|
||||
}
|
||||
|
||||
choices.values().map(|c| c.0).max().unwrap()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
for input in INPUTS.iter() {
|
||||
let output = parse(input);
|
||||
let score = solution(output);
|
||||
println!("{}", score);
|
||||
}
|
||||
}
|
||||
#[bench]
|
||||
fn solution_bench(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
let input = parse(INPUTS[1]);
|
||||
let result = solution(input);
|
||||
test::black_box(result);
|
||||
})
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
Valve GS has flow rate=0; tunnels lead to valves KB, GW
|
||||
Valve CB has flow rate=0; tunnels lead to valves GW, CT
|
||||
Valve TP has flow rate=0; tunnels lead to valves LR, TH
|
||||
Valve FI has flow rate=3; tunnels lead to valves DA, AY, ZO, MP, XP
|
||||
Valve WV has flow rate=0; tunnels lead to valves TH, HG
|
||||
Valve EA has flow rate=16; tunnels lead to valves PL, NG, AX
|
||||
Valve AT has flow rate=9; tunnels lead to valves ZO, EM
|
||||
Valve WS has flow rate=0; tunnels lead to valves GW, RD
|
||||
Valve MP has flow rate=0; tunnels lead to valves AA, FI
|
||||
Valve GE has flow rate=0; tunnels lead to valves AX, QN
|
||||
Valve SA has flow rate=10; tunnels lead to valves NI, OM, RD, RC, GO
|
||||
Valve NI has flow rate=0; tunnels lead to valves SA, YG
|
||||
Valve GO has flow rate=0; tunnels lead to valves TH, SA
|
||||
Valve IT has flow rate=0; tunnels lead to valves WB, KB
|
||||
Valve NG has flow rate=0; tunnels lead to valves EA, KF
|
||||
Valve RD has flow rate=0; tunnels lead to valves SA, WS
|
||||
Valve LR has flow rate=12; tunnels lead to valves TP, XR
|
||||
Valve TO has flow rate=22; tunnel leads to valve VW
|
||||
Valve WF has flow rate=0; tunnels lead to valves XX, OO
|
||||
Valve YD has flow rate=21; tunnel leads to valve NR
|
||||
Valve XR has flow rate=0; tunnels lead to valves LR, KB
|
||||
Valve KF has flow rate=0; tunnels lead to valves GW, NG
|
||||
Valve OO has flow rate=0; tunnels lead to valves UD, WF
|
||||
Valve HG has flow rate=0; tunnels lead to valves WV, YG
|
||||
Valve CT has flow rate=0; tunnels lead to valves YG, CB
|
||||
Valve DA has flow rate=0; tunnels lead to valves TH, FI
|
||||
Valve YY has flow rate=0; tunnels lead to valves AA, YG
|
||||
Valve VW has flow rate=0; tunnels lead to valves TO, EM
|
||||
Valve RC has flow rate=0; tunnels lead to valves AA, SA
|
||||
Valve PL has flow rate=0; tunnels lead to valves AA, EA
|
||||
Valve TH has flow rate=14; tunnels lead to valves GO, WV, GJ, DA, TP
|
||||
Valve QN has flow rate=24; tunnels lead to valves LC, GE
|
||||
Valve XE has flow rate=0; tunnels lead to valves NA, XX
|
||||
Valve XP has flow rate=0; tunnels lead to valves FI, OM
|
||||
Valve AX has flow rate=0; tunnels lead to valves GE, EA
|
||||
Valve EM has flow rate=0; tunnels lead to valves AT, VW
|
||||
Valve NR has flow rate=0; tunnels lead to valves YD, PM
|
||||
Valve YG has flow rate=4; tunnels lead to valves AY, HG, NI, YY, CT
|
||||
Valve PM has flow rate=0; tunnels lead to valves UD, NR
|
||||
Valve AY has flow rate=0; tunnels lead to valves YG, FI
|
||||
Valve GJ has flow rate=0; tunnels lead to valves AA, TH
|
||||
Valve LC has flow rate=0; tunnels lead to valves QN, GW
|
||||
Valve UD has flow rate=17; tunnels lead to valves OO, PM
|
||||
Valve AA has flow rate=0; tunnels lead to valves MP, GJ, YY, RC, PL
|
||||
Valve OM has flow rate=0; tunnels lead to valves XP, SA
|
||||
Valve WB has flow rate=0; tunnels lead to valves NA, IT
|
||||
Valve GW has flow rate=11; tunnels lead to valves KF, GS, LC, CB, WS
|
||||
Valve NA has flow rate=7; tunnels lead to valves WB, XE
|
||||
Valve XX has flow rate=20; tunnels lead to valves XE, WF
|
||||
Valve ZO has flow rate=0; tunnels lead to valves AT, FI
|
||||
Valve KB has flow rate=8; tunnels lead to valves XR, GS, IT
|
|
@ -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
|
Loading…
Reference in New Issue