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::convert::*;
use std::fs::File;
@ -25,7 +24,6 @@ impl From<(Vec<Resource>, usize)> for ResourceBuilder {
#[derive(Default, Debug)]
struct NanoFactory {
pipeline: Pipeline,
storage: HashMap<Resource, usize>,
}
#[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<Resource, usize> = HashMap::new();
self.lookup_resource(&mut storage, "FUEL")
}
fn lookup_resource(
storage: &mut HashMap<Resource, usize>,
pipeline: &Pipeline,
resource: &str,
) -> usize {
fn generate_fuel_from_ores(&self, ores: usize) -> usize {
let mut storage: HashMap<Resource, usize> = 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, usize>, 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);
}
}