From 2b714b646b23cc0721e70314000b66a86a68a2c7 Mon Sep 17 00:00:00 2001 From: Stefan Schwarz Date: Sat, 23 May 2020 10:49:59 +0200 Subject: [PATCH] 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) }