This commit is contained in:
Stefan Schwarz 2020-05-24 13:11:02 +02:00
parent 9a1baf1742
commit 07f3a06104

View file

@ -1,4 +1,3 @@
use std::borrow::{Borrow, BorrowMut};
use std::collections::HashMap; use std::collections::HashMap;
use std::convert::*; use std::convert::*;
use std::fs::File; use std::fs::File;
@ -25,7 +24,6 @@ impl From<(Vec<Resource>, usize)> for ResourceBuilder {
#[derive(Default, Debug)] #[derive(Default, Debug)]
struct NanoFactory { struct NanoFactory {
pipeline: Pipeline, pipeline: Pipeline,
storage: HashMap<Resource, usize>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -38,46 +36,74 @@ enum NanoFactoryBuildState {
} }
impl NanoFactory { impl NanoFactory {
fn generate_fuel(&mut self) -> usize { fn generate_fuel(&self) -> usize {
let storage = self.storage.borrow_mut(); let mut storage: HashMap<Resource, usize> = HashMap::new();
let pipeline = self.pipeline.borrow(); self.lookup_resource(&mut storage, "FUEL")
return NanoFactory::lookup_resource(storage, pipeline, "FUEL");
} }
fn lookup_resource( fn generate_fuel_from_ores(&self, ores: usize) -> usize {
storage: &mut HashMap<Resource, usize>, let mut storage: HashMap<Resource, usize> = HashMap::new();
pipeline: &Pipeline, let mut fuel_for_even = 0;
resource: &str, let mut ores_for_even = 0;
) -> usize { loop {
fuel_for_even += 1;
ores_for_even += self.lookup_resource(&mut storage, "FUEL");
if storage.iter().all(|(_, v)| *v == 0) {
break;
}
}
println!(
"fuels_for_even:{} ores_for_even:{}",
fuel_for_even, ores_for_even
);
let steps = ores / ores_for_even;
println!("{}", steps);
let mut fuel = fuel_for_even * steps;
let mut ores = ores - (ores_for_even * steps);
loop {
let cost = self.lookup_resource(&mut storage, "FUEL");
if cost > ores {
break;
}
ores -= cost;
fuel += 1;
}
fuel
}
fn lookup_resource(&self, storage: &mut HashMap<Resource, usize>, resource: &str) -> usize {
if resource == "ORE" { if resource == "ORE" {
return 1; return 1;
} }
// use from storage // use from storage
if let Some(count) = storage.get_mut(resource.into()) { if let Some(count) = storage.get_mut(resource) {
if *count > 0 { if *count > 0 {
*count -= 1; *count -= 1;
return 0; return 0;
} }
} }
// cloned to still allow writable acces to self
let required = pipeline
.get(resource.into())
.expect("unable to find resource");
// initialize storage with zero // initialize storage with zero
if let None = storage.get(resource.into()) { if storage.get(resource).is_none() {
storage.insert(resource.into(), 0); storage.insert(resource.into(), 0);
} }
// build resource and and to storage // build resource and and to storage
let stored = storage.get_mut(resource.into()).unwrap(); let required = self
*stored += required.out_count - 1; .pipeline
required.requirements.iter().fold(0, |mut acc, c| { .get(resource)
acc += NanoFactory::lookup_resource(storage, pipeline, c); .expect("unable to find resource");
let cost = required.requirements.iter().fold(0, |mut acc, c| {
acc += self.lookup_resource(storage, c);
acc acc
}) });
// update storage
let stored = storage.get_mut(resource).unwrap();
*stored += required.out_count - 1;
cost
} }
} }
@ -182,9 +208,12 @@ where
fn main() { fn main() {
let f = File::open("input14").unwrap(); let f = File::open("input14").unwrap();
let bufreader = BufReader::new(f); let bufreader = BufReader::new(f);
let mut factory = NanoFactory::from(bufreader); let factory = NanoFactory::from(bufreader);
let ores = factory.generate_fuel(); println!("ores: {}", factory.generate_fuel());
println!("ores: {}", ores); println!(
"ores: {}",
factory.generate_fuel_from_ores(1_000_000_000_000)
);
} }
#[cfg(test)] #[cfg(test)]
@ -204,9 +233,8 @@ mod tests {
.trim() .trim()
.as_bytes(), .as_bytes(),
); );
let mut factory = NanoFactory::from(bufreader); let factory = NanoFactory::from(bufreader);
let ores = factory.generate_fuel(); assert_eq!(factory.generate_fuel(), 31);
assert_eq!(ores, 31)
} }
#[test] #[test]
@ -224,9 +252,8 @@ mod tests {
.trim() .trim()
.as_bytes(), .as_bytes(),
); );
let mut factory = NanoFactory::from(bufreader); let factory = NanoFactory::from(bufreader);
let ores = factory.generate_fuel(); assert_eq!(factory.generate_fuel(), 165)
assert_eq!(ores, 165)
} }
#[test] #[test]
@ -246,9 +273,9 @@ mod tests {
.trim() .trim()
.as_bytes(), .as_bytes(),
); );
let mut factory = NanoFactory::from(bufreader); let factory = NanoFactory::from(bufreader);
let ores = factory.generate_fuel(); assert_eq!(factory.generate_fuel(), 13312);
assert_eq!(ores, 13312) assert_eq!(factory.generate_fuel_from_ores(1_000_000_000_000), 82892753);
} }
#[test] #[test]
@ -271,9 +298,9 @@ mod tests {
.trim() .trim()
.as_bytes(), .as_bytes(),
); );
let mut factory = NanoFactory::from(bufreader); let factory = NanoFactory::from(bufreader);
let ores = factory.generate_fuel(); assert_eq!(factory.generate_fuel(), 180697);
assert_eq!(ores, 180697) assert_eq!(factory.generate_fuel_from_ores(1_000_000_000_000), 5586022);
} }
#[test] #[test]
@ -301,8 +328,8 @@ mod tests {
.trim() .trim()
.as_bytes(), .as_bytes(),
); );
let mut factory = NanoFactory::from(bufreader); let factory = NanoFactory::from(bufreader);
let ores = factory.generate_fuel(); assert_eq!(factory.generate_fuel(), 2210736);
assert_eq!(ores, 2210736) assert_eq!(factory.generate_fuel_from_ores(1_000_000_000_000), 460664);
} }
} }