diff --git a/2018/rust/src/bin/day_07.rs b/2018/rust/src/bin/day_07.rs index 6f4c2a7..ed71157 100644 --- a/2018/rust/src/bin/day_07.rs +++ b/2018/rust/src/bin/day_07.rs @@ -19,34 +19,19 @@ fn main() -> Result<(), Box> { } fn solve(input: &str) -> Result> { - let mut assembly: Assembly = input.parse()?; - let output = part_two(&mut assembly, 5, |x| (x as usize) - ('A' as usize) + 61); + let assembly: Assembly = input.parse()?; + let output = part_two(assembly, 5, |x| (x as usize) - ('A' as usize) + 61); Ok(output.to_string()) } -fn part_two usize>( - assembly: &mut Assembly, - worker_count: usize, - step_time: F, -) -> usize { - let mut workers = Workers(vec![None; worker_count]); - - let mut output = 0; - while !assembly.is_done() || workers.are_working() { - for (worker, step_id) in workers.available().iter_mut().zip(assembly.available()) { - worker.replace((step_id, step_time(step_id))); - assembly.start(step_id); - } - - let done = workers.tick(); - for step_id in done { - assembly.finish(step_id); - } - - output += 1; +fn part_two usize>(assembly: Assembly, worker_count: usize, step_time: F) -> usize { + let workers = Workers(vec![None; worker_count]); + PartTwo { + assembly, + workers, + step_time, } - - output + .count() } #[test] @@ -61,27 +46,52 @@ Step D must be finished before step E can begin. Step F must be finished before step E can begin. "; - let mut assembly: Assembly = input.parse().unwrap(); - let output = part_two(&mut assembly, 2, |x| (x as usize) - ('A' as usize) + 1); + let assembly: Assembly = input.parse().unwrap(); + let output = part_two(assembly, 2, |x| (x as usize) - ('A' as usize) + 1); assert_eq!(output, 15); } +struct PartTwo { + assembly: Assembly, + workers: Workers, + step_time: F, +} + +impl usize> Iterator for PartTwo { + type Item = Vec>; + + fn next(&mut self) -> Option { + if self.assembly.is_done() { + return None; + } + + for (worker, step_id) in self + .workers + .available() + .iter_mut() + .zip(self.assembly.available()) + { + worker.replace((step_id, (self.step_time)(step_id))); + self.assembly.start(step_id); + } + + let done = self.workers.tick(); + for step_id in done { + self.assembly.finish(step_id); + } + + Some(self.workers.0.iter().map(|x| x.map(|x| x.0)).collect()) + } +} + #[derive(Debug)] struct Workers(Vec>); impl Workers { - fn are_working(&self) -> bool { - !self.current_work().is_empty() - } - fn available(&mut self) -> Vec<&mut Option<(char, usize)>> { self.0.iter_mut().filter(|x| x.is_none()).collect() } - fn current_work(&self) -> Vec<&char> { - self.0.iter().flat_map(|x| x).map(|(x, _)| x).collect() - } - fn tick(&mut self) -> Vec { let mut done = Vec::new(); for maybe_work in self.0.iter_mut() {