day 14 task 2
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
fn parser(s: &str) -> Chemical {
|
fn parser(s: &str) -> Chemical {
|
||||||
let (n, t) = s.split(" ").collect_tuple().unwrap();
|
let (n, t) = s.split(" ").collect_tuple().unwrap();
|
||||||
@@ -25,6 +26,36 @@ pub fn run() {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
task1(&rules);
|
||||||
|
task2(&rules);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn task1(rules: &HashMap<&str, (usize, Vec<Chemical>)>) {
|
||||||
|
println!("Task 1: {} ORE is needed", calc_ore_for_fuel(1, rules));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn task2(rules: &HashMap<&str, (usize, Vec<Chemical>)>) {
|
||||||
|
const ORE_STORAGE: usize = 1_000_000_000_000;
|
||||||
|
// binary search max fuel
|
||||||
|
let (max_fuel, _) = std::iter::successors(Some((1, ORE_STORAGE)), |(min, max)| {
|
||||||
|
if max - min > 1 {
|
||||||
|
let middle = (max + min) / 2;
|
||||||
|
let ore = calc_ore_for_fuel(middle, rules);
|
||||||
|
if ore > ORE_STORAGE {
|
||||||
|
Some((*min, middle))
|
||||||
|
} else {
|
||||||
|
Some((middle, *max))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.last()
|
||||||
|
.unwrap();
|
||||||
|
println!("Task 2: the maximum amount of fuel is {}", max_fuel);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_ore_for_fuel(fuel: usize, rules: &HashMap<&str, (usize, Vec<Chemical>)>) -> usize {
|
||||||
/*
|
/*
|
||||||
The idea is: the rules create a DAG of requirements.
|
The idea is: the rules create a DAG of requirements.
|
||||||
We store for every chemical a list of the chemicals that rely on it.
|
We store for every chemical a list of the chemicals that rely on it.
|
||||||
@@ -52,7 +83,7 @@ pub fn run() {
|
|||||||
chem_used_by.insert("FUEL", vec![]);
|
chem_used_by.insert("FUEL", vec![]);
|
||||||
// the amount of a not processed chemical C, which is needed by the chemicals that rely on C
|
// the amount of a not processed chemical C, which is needed by the chemicals that rely on C
|
||||||
let mut requirements = HashMap::<&str, usize>::new();
|
let mut requirements = HashMap::<&str, usize>::new();
|
||||||
requirements.insert("FUEL", 1);
|
requirements.insert("FUEL", fuel);
|
||||||
while let Some((name, amount)) = requirements
|
while let Some((name, amount)) = requirements
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(name, _)| chem_used_by[*name].is_empty() && **name != "ORE")
|
.find(|(name, _)| chem_used_by[*name].is_empty() && **name != "ORE")
|
||||||
@@ -77,7 +108,7 @@ pub fn run() {
|
|||||||
}
|
}
|
||||||
requirements.remove(name);
|
requirements.remove(name);
|
||||||
}
|
}
|
||||||
println!("Task 1: {} ORE is needed", requirements["ORE"]);
|
requirements["ORE"]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
|
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
|
||||||
|
|||||||
Reference in New Issue
Block a user