day 14 task 2

This commit is contained in:
Johannes
2019-12-14 22:01:01 +01:00
parent 83dce003d8
commit 71d068ab2c

View File

@@ -1,6 +1,7 @@
use itertools::Itertools;
use std::collections::HashMap;
#[allow(dead_code)]
pub fn run() {
fn parser(s: &str) -> Chemical {
let (n, t) = s.split(" ").collect_tuple().unwrap();
@@ -25,6 +26,36 @@ pub fn run() {
)
})
.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.
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![]);
// 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();
requirements.insert("FUEL", 1);
requirements.insert("FUEL", fuel);
while let Some((name, amount)) = requirements
.iter()
.find(|(name, _)| chem_used_by[*name].is_empty() && **name != "ORE")
@@ -77,7 +108,7 @@ pub fn run() {
}
requirements.remove(name);
}
println!("Task 1: {} ORE is needed", requirements["ORE"]);
requirements["ORE"]
}
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]