From c478736d46e9abb55ee58497d3317e729a4c570c Mon Sep 17 00:00:00 2001 From: Stefan Schwarz Date: Fri, 22 May 2020 17:55:22 +0200 Subject: [PATCH 1/5] wip --- Cargo.toml | 10 +++++- src/day14/main.rs | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 src/day14/main.rs diff --git a/Cargo.toml b/Cargo.toml index 3ee5431..ba432d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,4 +36,12 @@ path = "src/day9/main.rs" [[bin]] name = "day10" -path = "src/day10/main.rs" \ No newline at end of file +path = "src/day10/main.rs" + +[[bin]] +name = "day12" +path = "src/day12/main.rs" + +[[bin]] +name = "day14" +path = "src/day14/main.rs" diff --git a/src/day14/main.rs b/src/day14/main.rs new file mode 100644 index 0000000..5ba72da --- /dev/null +++ b/src/day14/main.rs @@ -0,0 +1,78 @@ +use std::collections::HashMap; +use std::fs::File; +use std::io::{BufRead, BufReader}; +use std::iter::Peekable; + +type Resource = String; +type Requirements = HashMap>; + +#[derive(Default)] +struct NanoFactory { + requirements: Requirements, +} + +enum NanoFactoryBuildState { + InputCount, + InputResource, + InputDivider, + OutputArrow, + OutputCount, + OutputResource, +} + +impl From for NanoFactory +where + T: BufRead, +{ + fn from(bufreader: T) -> Self { + let f = NanoFactory::default(); + let mut state = NanoFactoryBuildState::InputCount; + bufreader.split(b'\n').for_each(|line| { + let line = line.unwrap(); + let mut line = line.into_iter().peekable(); + let mut count_var = 0; + match state { + NanoFactoryBuildState::InputCount => { + let test = next_if_in_range(&mut line, 48..84); + println!("{:?}", test); + while let Some(_) = line.peek().and_then(|c| match c { + 48..=57 => Some(c), + _ => None, + }) { + count_var = count_var * 10 + line.next().unwrap() as usize; + } + assert_eq!(line.next().unwrap(), b' '); + state = NanoFactoryBuildState::InputResource; + } + NanoFactoryBuildState::InputResource => {} + _ => (), + }; + line.for_each(|c| match c { + b'0'..=b'9' => println!("test:{}", c), + _ => (), + }) + }); + NanoFactory { + requirements: Default::default(), + } + } +} + +fn next_if_in_range( + peekable: &mut std::iter::Peekable, + range: std::ops::Range, +) -> Option<&T> +where + I: std::iter::Iterator, +{ + peekable.peek().and_then(|peeked| match peeked { + range => Some(peeked), + _ => None, + }) +} + +fn main() { + let f = File::open("input14").unwrap(); + let bufreader = BufReader::new(f); + let factory = NanoFactory::from(bufreader); +} From 2b714b646b23cc0721e70314000b66a86a68a2c7 Mon Sep 17 00:00:00 2001 From: Stefan Schwarz Date: Sat, 23 May 2020 10:49:59 +0200 Subject: [PATCH 2/5] wip --- input14 | 6 ++ src/day14/main.rs | 159 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 128 insertions(+), 37 deletions(-) create mode 100644 input14 diff --git a/input14 b/input14 new file mode 100644 index 0000000..65ad5cc --- /dev/null +++ b/input14 @@ -0,0 +1,6 @@ +10 ORE => 10 A +1 ORE => 1 B +7 A, 1 B => 1 C +7 A, 1 C => 1 D +7 A, 1 D => 1 E +7 A, 1 E => 1 FUEL diff --git a/src/day14/main.rs b/src/day14/main.rs index 5ba72da..a393f67 100644 --- a/src/day14/main.rs +++ b/src/day14/main.rs @@ -1,78 +1,163 @@ use std::collections::HashMap; use std::fs::File; use std::io::{BufRead, BufReader}; -use std::iter::Peekable; type Resource = String; -type Requirements = HashMap>; +type Pipeline = HashMap; -#[derive(Default)] -struct NanoFactory { - requirements: Requirements, +#[derive(Debug)] +struct ResourceBuilder { + requirements: Vec, + out_count: usize, } +impl From<(Vec, usize)> for ResourceBuilder { + fn from(build: (Vec, usize)) -> Self { + ResourceBuilder { + requirements: build.0, + out_count: build.1, + } + } +} + +#[derive(Default, Debug)] +struct NanoFactory { + pipeline: Pipeline, + storage: HashMap, +} + +#[derive(Debug)] enum NanoFactoryBuildState { InputCount, InputResource, - InputDivider, OutputArrow, OutputCount, OutputResource, } +impl NanoFactory { + fn generate_fuel(&mut self) -> usize { + return self.lookup_resource("FUEL"); + } + + fn lookup_resource(&mut self, resource: &str) -> usize { + if resource == "ORE" { + return 1; + } + if let Some(count) = self.storage.get_mut(resource.into()) { + *count -= 1 + } + let pipeline = self.pipeline.as_mut_ref(); + let required = self + .pipeline + .get(resource.into()) + .expect("unable to find resource"); + required.requirements.iter().fold(0, |mut acc, c| { + acc += self.lookup_resource(c); + acc + }) + } +} + impl From for NanoFactory where T: BufRead, { fn from(bufreader: T) -> Self { - let f = NanoFactory::default(); + let mut f = NanoFactory::default(); let mut state = NanoFactoryBuildState::InputCount; - bufreader.split(b'\n').for_each(|line| { + bufreader.split(b'\n').enumerate().for_each(|(nr, line)| { let line = line.unwrap(); let mut line = line.into_iter().peekable(); let mut count_var = 0; - match state { - NanoFactoryBuildState::InputCount => { - let test = next_if_in_range(&mut line, 48..84); - println!("{:?}", test); - while let Some(_) = line.peek().and_then(|c| match c { - 48..=57 => Some(c), - _ => None, - }) { - count_var = count_var * 10 + line.next().unwrap() as usize; + let mut cur_requirements = Vec::new(); + loop { + match state { + NanoFactoryBuildState::InputCount | NanoFactoryBuildState::OutputCount => { + while let Some(c) = next_if_in_range(&mut line, 48..=57) { + count_var = count_var * 10 + (c as usize) - 48; + } + assert_eq!(line.next().unwrap(), b' '); + state = match state { + NanoFactoryBuildState::InputCount => { + NanoFactoryBuildState::InputResource + } + NanoFactoryBuildState::OutputCount => { + NanoFactoryBuildState::OutputResource + } + _ => unreachable!(), + } } - assert_eq!(line.next().unwrap(), b' '); - state = NanoFactoryBuildState::InputResource; - } - NanoFactoryBuildState::InputResource => {} - _ => (), - }; - line.for_each(|c| match c { - b'0'..=b'9' => println!("test:{}", c), - _ => (), - }) + NanoFactoryBuildState::InputResource => { + let mut r = Resource::new(); + while let Some(c) = next_if_in_range(&mut line, 65..=90) { + r.push(c.into()); + } + for _ in 0..count_var { + cur_requirements.push(r.clone()); + } + r.truncate(0); + count_var = 0; + let next = line.next(); + match next { + Some(b',') => { + assert_eq!(line.next().unwrap(), b' '); + state = NanoFactoryBuildState::InputCount; + } + Some(b' ') => state = NanoFactoryBuildState::OutputArrow, + _ => panic!( + "invalid format in line {}, expected ' ' or ',', got '{:?}'", + nr, next + ), + } + } + NanoFactoryBuildState::OutputResource => { + let mut r = Resource::new(); + while let Some(c) = next_if_in_range(&mut line, 65..=90) { + r.push(c.into()); + } + f.pipeline + .insert(r, ResourceBuilder::from((cur_requirements, count_var))); + state = NanoFactoryBuildState::InputCount; + return; + } + NanoFactoryBuildState::OutputArrow => { + assert_eq!(line.next().unwrap(), b'='); + assert_eq!(line.next().unwrap(), b'>'); + assert_eq!(line.next().unwrap(), b' '); + state = NanoFactoryBuildState::OutputCount + } + }; + } }); - NanoFactory { - requirements: Default::default(), - } + println! {"{:?}", f}; + f } } fn next_if_in_range( peekable: &mut std::iter::Peekable, - range: std::ops::Range, -) -> Option<&T> + range: std::ops::RangeInclusive, +) -> Option where I: std::iter::Iterator, + T: Copy + std::cmp::PartialOrd, { - peekable.peek().and_then(|peeked| match peeked { - range => Some(peeked), - _ => None, - }) + if let Some(peeked) = peekable.peek() { + if range.contains(peeked) { + peekable.next() + } else { + None + } + } else { + None + } } fn main() { let f = File::open("input14").unwrap(); let bufreader = BufReader::new(f); - let factory = NanoFactory::from(bufreader); + let mut factory = NanoFactory::from(bufreader); + let ores = factory.generate_fuel(); + println!("ores: {}", ores) } From 1818cda54f647ed49640c1a3043194b160657fd4 Mon Sep 17 00:00:00 2001 From: Stefan Schwarz Date: Sat, 23 May 2020 10:52:25 +0200 Subject: [PATCH 3/5] up --- src/day14/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/day14/main.rs b/src/day14/main.rs index a393f67..3ac25fd 100644 --- a/src/day14/main.rs +++ b/src/day14/main.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::convert::*; use std::fs::File; use std::io::{BufRead, BufReader}; @@ -47,7 +48,7 @@ impl NanoFactory { if let Some(count) = self.storage.get_mut(resource.into()) { *count -= 1 } - let pipeline = self.pipeline.as_mut_ref(); + let pipeline = self.pipeline.as_mut(); let required = self .pipeline .get(resource.into()) From 9a1baf1742fa962f5d063fbafd3106e95dcb7e41 Mon Sep 17 00:00:00 2001 From: Stefan Schwarz Date: Sat, 23 May 2020 11:29:50 +0200 Subject: [PATCH 4/5] day14part1 working --- input14 | 62 ++++++++++++++++-- src/day14/main.rs | 164 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 210 insertions(+), 16 deletions(-) diff --git a/input14 b/input14 index 65ad5cc..ea6fb95 100644 --- a/input14 +++ b/input14 @@ -1,6 +1,56 @@ -10 ORE => 10 A -1 ORE => 1 B -7 A, 1 B => 1 C -7 A, 1 C => 1 D -7 A, 1 D => 1 E -7 A, 1 E => 1 FUEL +18 FHWM => 1 XGQNZ +4 FVPWN, 9 CQGW => 7 QGHT +22 KZMS, 1 DMCJL => 8 TWGCK +1 LMGQN, 1 DSWDM, 1 GKGZ => 1 TGPH +22 WCSW => 1 LVTG +13 JSWR => 4 GKGZ +162 ORE => 3 FVPWN +59 CQGW, 15 MSNG, 6 XGKRF, 10 LJRQ, 1 HRKGV, 15 RKVC => 1 FUEL +5 DMCJL => 1 QBLH +2 XDRJ, 2 RKVC => 8 CTCNL +1 QXHX => 5 GFPSK +22 QGHT, 6 GFPSK, 5 DHTPL => 3 CSDR +4 QGHT, 2 HFXD => 4 XDRJ +10 WQCGV, 1 JSWR, 21 RHTLN => 7 VTPC +11 CQGW, 1 FVPWN => 3 HFXD +5 VTPC => 2 NCXW +8 LDZVS => 6 DQLH +117 ORE => 2 KWZNB +3 TGPH, 1 JPFQ, 2 WHWLK, 5 RKVC, 16 DQLH => 9 LJRQ +14 KWZNB, 2 CQGW => 8 MLPK +6 LDZVS => 2 JSWR +1 RKVC, 8 HCGT, 9 DHTPL => 6 FHWM +3 DHTPL, 1 HWSR, 36 LDZVS => 6 DSWDM +5 WHWLK, 1 LJHWT, 8 HSTHS => 7 VMPX +22 ZJCDZ, 3 WQCGV => 5 DHTPL +10 LJHWT, 32 GFPSK, 2 RHTLN => 4 HFRMP +2 FKVD, 3 TWGCK, 1 HWSR => 1 RNLZW +2 CSDR, 3 DQLH, 2 HSTHS => 9 JPFQ +1 JSWR, 1 PCWS, 1 HFRMP => 3 XGKRF +2 QGHT, 9 LVTG, 3 QBLH => 7 RHTLN +10 LJHWT, 4 CTCNL => 8 QXHX +16 MLPK, 1 HFXD => 9 ZJCDZ +6 QGHT => 9 WCSW +4 HWSR, 4 MLPK, 1 KZMS => 3 BGZHQ +12 MLPK => 8 RKVC +1 HWSR, 1 VNWFS => 7 BGFJ +7 FHWM, 11 CTDF, 1 LDZVS => 2 VNWFS +4 CTDF => 4 HSTHS +2 ZJCDZ => 6 LJHWT +1 VMPX, 1 NCXW, 1 HSTHS, 41 XGKRF, 30 HLNG, 1 GKGZ => 7 HRKGV +1 XGQNZ, 10 PCWS, 3 BGFJ => 8 FKVD +1 GFPSK, 1 DMCJL, 1 LVTG => 5 XDTZB +3 WCSW => 5 KZMS +6 TWGCK, 1 QXHX, 4 BGFJ => 2 LMGQN +1 WCSW => 7 LDZVS +1 XDTZB, 9 VNWFS => 3 WHWLK +3 HFXD, 4 WCSW, 1 MLPK => 5 WQCGV +2 BGFJ, 1 HSTHS, 22 MDCB, 10 HWSR, 6 RNLZW, 8 GKGZ => 5 MSNG +4 QGHT, 1 FKVD => 7 MDCB +9 MLPK, 3 LJHWT => 7 DMCJL +121 ORE => 2 CQGW +9 DHTPL, 2 BGZHQ => 8 CTDF +2 JSWR, 30 RHTLN => 7 HLNG +2 QBLH => 7 PCWS +14 LVTG => 8 HWSR +7 DMCJL => 1 HCGT diff --git a/src/day14/main.rs b/src/day14/main.rs index 3ac25fd..df261fa 100644 --- a/src/day14/main.rs +++ b/src/day14/main.rs @@ -1,3 +1,4 @@ +use std::borrow::{Borrow, BorrowMut}; use std::collections::HashMap; use std::convert::*; use std::fs::File; @@ -38,23 +39,43 @@ enum NanoFactoryBuildState { impl NanoFactory { fn generate_fuel(&mut self) -> usize { - return self.lookup_resource("FUEL"); + let storage = self.storage.borrow_mut(); + let pipeline = self.pipeline.borrow(); + return NanoFactory::lookup_resource(storage, pipeline, "FUEL"); } - fn lookup_resource(&mut self, resource: &str) -> usize { + fn lookup_resource( + storage: &mut HashMap, + pipeline: &Pipeline, + resource: &str, + ) -> usize { if resource == "ORE" { return 1; } - if let Some(count) = self.storage.get_mut(resource.into()) { - *count -= 1 + + // use from storage + if let Some(count) = storage.get_mut(resource.into()) { + if *count > 0 { + *count -= 1; + return 0; + } } - let pipeline = self.pipeline.as_mut(); - let required = self - .pipeline + + // 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()) { + 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 += self.lookup_resource(c); + acc += NanoFactory::lookup_resource(storage, pipeline, c); acc }) } @@ -74,6 +95,7 @@ where let mut cur_requirements = Vec::new(); loop { match state { + // numeric input NanoFactoryBuildState::InputCount | NanoFactoryBuildState::OutputCount => { while let Some(c) = next_if_in_range(&mut line, 48..=57) { count_var = count_var * 10 + (c as usize) - 48; @@ -89,6 +111,7 @@ where _ => unreachable!(), } } + // input resouce name NanoFactoryBuildState::InputResource => { let mut r = Resource::new(); while let Some(c) = next_if_in_range(&mut line, 65..=90) { @@ -112,6 +135,7 @@ where ), } } + // output resource name NanoFactoryBuildState::OutputResource => { let mut r = Resource::new(); while let Some(c) = next_if_in_range(&mut line, 65..=90) { @@ -122,6 +146,7 @@ where state = NanoFactoryBuildState::InputCount; return; } + // arrow between input and output ' => ' NanoFactoryBuildState::OutputArrow => { assert_eq!(line.next().unwrap(), b'='); assert_eq!(line.next().unwrap(), b'>'); @@ -131,7 +156,6 @@ where }; } }); - println! {"{:?}", f}; f } } @@ -160,5 +184,125 @@ fn main() { let bufreader = BufReader::new(f); let mut factory = NanoFactory::from(bufreader); let ores = factory.generate_fuel(); - println!("ores: {}", ores) + println!("ores: {}", ores); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn example1() { + let bufreader = BufReader::new( + "10 ORE => 10 A +1 ORE => 1 B +7 A, 1 B => 1 C +7 A, 1 C => 1 D +7 A, 1 D => 1 E +7 A, 1 E => 1 FUEL +" + .trim() + .as_bytes(), + ); + let mut factory = NanoFactory::from(bufreader); + let ores = factory.generate_fuel(); + assert_eq!(ores, 31) + } + + #[test] + fn example2() { + let bufreader = BufReader::new( + " +9 ORE => 2 A +8 ORE => 3 B +7 ORE => 5 C +3 A, 4 B => 1 AB +5 B, 7 C => 1 BC +4 C, 1 A => 1 CA +2 AB, 3 BC, 4 CA => 1 FUEL +" + .trim() + .as_bytes(), + ); + let mut factory = NanoFactory::from(bufreader); + let ores = factory.generate_fuel(); + assert_eq!(ores, 165) + } + + #[test] + fn example3() { + let bufreader = BufReader::new( + " +157 ORE => 5 NZVS +165 ORE => 6 DCFZ +44 XJWVT, 5 KHKGT, 1 QDVJ, 29 NZVS, 9 GPVTF, 48 HKGWZ => 1 FUEL +12 HKGWZ, 1 GPVTF, 8 PSHF => 9 QDVJ +179 ORE => 7 PSHF +177 ORE => 5 HKGWZ +7 DCFZ, 7 PSHF => 2 XJWVT +165 ORE => 2 GPVTF +3 DCFZ, 7 NZVS, 5 HKGWZ, 10 PSHF => 8 KHKGT +" + .trim() + .as_bytes(), + ); + let mut factory = NanoFactory::from(bufreader); + let ores = factory.generate_fuel(); + assert_eq!(ores, 13312) + } + + #[test] + fn example4() { + let bufreader = BufReader::new( + " +2 VPVL, 7 FWMGM, 2 CXFTF, 11 MNCFX => 1 STKFG +17 NVRVD, 3 JNWZP => 8 VPVL +53 STKFG, 6 MNCFX, 46 VJHF, 81 HVMC, 68 CXFTF, 25 GNMV => 1 FUEL +22 VJHF, 37 MNCFX => 5 FWMGM +139 ORE => 4 NVRVD +144 ORE => 7 JNWZP +5 MNCFX, 7 RFSQX, 2 FWMGM, 2 VPVL, 19 CXFTF => 3 HVMC +5 VJHF, 7 MNCFX, 9 VPVL, 37 CXFTF => 6 GNMV +145 ORE => 6 MNCFX +1 NVRVD => 8 CXFTF +1 VJHF, 6 MNCFX => 4 RFSQX +176 ORE => 6 VJHF +" + .trim() + .as_bytes(), + ); + let mut factory = NanoFactory::from(bufreader); + let ores = factory.generate_fuel(); + assert_eq!(ores, 180697) + } + + #[test] + fn example5() { + let bufreader = BufReader::new( + " +171 ORE => 8 CNZTR +7 ZLQW, 3 BMBT, 9 XCVML, 26 XMNCP, 1 WPTQ, 2 MZWV, 1 RJRHP => 4 PLWSL +114 ORE => 4 BHXH +14 VRPVC => 6 BMBT +6 BHXH, 18 KTJDG, 12 WPTQ, 7 PLWSL, 31 FHTLT, 37 ZDVW => 1 FUEL +6 WPTQ, 2 BMBT, 8 ZLQW, 18 KTJDG, 1 XMNCP, 6 MZWV, 1 RJRHP => 6 FHTLT +15 XDBXC, 2 LTCX, 1 VRPVC => 6 ZLQW +13 WPTQ, 10 LTCX, 3 RJRHP, 14 XMNCP, 2 MZWV, 1 ZLQW => 1 ZDVW +5 BMBT => 4 WPTQ +189 ORE => 9 KTJDG +1 MZWV, 17 XDBXC, 3 XCVML => 2 XMNCP +12 VRPVC, 27 CNZTR => 2 XDBXC +15 KTJDG, 12 BHXH => 5 XCVML +3 BHXH, 2 VRPVC => 7 MZWV +121 ORE => 7 VRPVC +7 XCVML => 6 RJRHP +5 BHXH, 4 VRPVC => 5 LTCX +" + .trim() + .as_bytes(), + ); + let mut factory = NanoFactory::from(bufreader); + let ores = factory.generate_fuel(); + assert_eq!(ores, 2210736) + } } From 07f3a06104c2b5ef8b988c29b3cab6fb8fd3187d Mon Sep 17 00:00:00 2001 From: Stefan Schwarz Date: Sun, 24 May 2020 13:11:02 +0200 Subject: [PATCH 5/5] a try --- src/day14/main.rs | 109 +++++++++++++++++++++++++++++----------------- 1 file changed, 68 insertions(+), 41 deletions(-) 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); } }