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