From dfb8421decc478319cc6262f1154a151546b4fc6 Mon Sep 17 00:00:00 2001 From: Max Nuding Date: Sun, 11 Dec 2022 13:26:28 +0000 Subject: [PATCH] Refactored computer --- src/day10/mod.rs | 133 +++++++++++++++++++++++++++++------------------ 1 file changed, 83 insertions(+), 50 deletions(-) diff --git a/src/day10/mod.rs b/src/day10/mod.rs index 763924d..32237a1 100644 --- a/src/day10/mod.rs +++ b/src/day10/mod.rs @@ -27,67 +27,100 @@ impl Command { } } -pub fn run() { +struct Puter { + register_x: (i32, i32), + cycle: usize, + pixel_row: [bool; Puter::LINE_WIDTH], + rows: Vec, + cycles_processing_left: usize, + + signal_strengths: Vec, +} + +impl Puter { const LINE_WIDTH: usize = 40; const SPRITE_WIDTH: usize = 3; - const SPRITE_WIDTH_HALF: usize = SPRITE_WIDTH / 2; + const SPRITE_WIDTH_HALF: usize = Puter::SPRITE_WIDTH / 2; - let input = read("10"); - let mut lines = input.lines(); - - let mut cycle = 1; - let mut is_busy = 0; - let mut v: i32 = 1; - let mut v_new: i32 = 1; - let mut sig_str = vec![]; - let mut pixels = [false; LINE_WIDTH]; - let mut rows = vec![]; - 'outer: loop { - // Part 1 - if cycle == 20 || (cycle > 20 && (cycle - 20) % LINE_WIDTH == 0) { - sig_str.push(cycle as i32 * v); + pub fn new() -> Self { + Self { + register_x: (1, 1), + cycle: 1, + pixel_row: [false; Puter::LINE_WIDTH], + rows: Vec::with_capacity(6), + cycles_processing_left: 0, + signal_strengths: Vec::with_capacity(6), } - - if is_busy == 0 { - match lines.next() { - Some(s) => { - let cmd = Command::from_str(s); - match cmd { - Command::Noop => {} - Command::AddX(x) => { - v_new += x; - } - }; - is_busy = cmd.num_cycles(); - } - _ => { - break 'outer; - } - }; - } - is_busy -= 1; - - let pixel = (cycle - 1) % LINE_WIDTH; - let is_lit = pixel.abs_diff(v as usize) <= SPRITE_WIDTH_HALF; - pixels[pixel] = is_lit; - if pixel == LINE_WIDTH - 1 { - let row: String = pixels.map(|l| if l { '#' } else { ' ' }).iter().collect(); - rows.push(row); - } - - if is_busy == 0 { - v = v_new; - } - cycle += 1; } + fn execute(&mut self, cmd: Command) { + match cmd { + Command::Noop => {} + Command::AddX(v) => { + self.register_x.1 += v; + } + }; + self.cycles_processing_left = cmd.num_cycles(); + } + + pub fn run(&mut self, program: &str) { + let mut lines = program.lines(); + loop { + if self.cycles_processing_left == 0 { + match lines.next() { + Some(s) => self.execute(Command::from_str(s)), + _ => return, + }; + } + + self.cycles_processing_left -= 1; + + let pixel = (self.cycle - 1) % Puter::LINE_WIDTH; + let is_lit = pixel.abs_diff(self.register_x.0 as usize) <= Puter::SPRITE_WIDTH_HALF; + self.pixel_row[pixel] = is_lit; + if pixel == Puter::LINE_WIDTH - 1 { + self.rows.push( + self.pixel_row + .map(|l| if l { '#' } else { ' ' }) + .iter() + .collect(), + ); + } else if pixel == (Puter::LINE_WIDTH / 2) - 1 { + self.signal_strengths + .push(self.cycle as i32 * self.register_x.0); + } + + if self.cycles_processing_left == 0 { + self.register_x.0 = self.register_x.1; + } + self.cycle += 1; + } + } + + pub fn signal_strengths(&self) -> Vec { + self.signal_strengths.clone() + } + + pub fn output(&self) -> Vec { + self.rows.clone() + } +} + +pub fn run() { + let input = read("10"); + let mut device = Puter::new(); + device.run(&input); + #[cfg(feature = "part1")] { - println!("Day 10, Part 01: {}", sig_str.iter().sum::()); + println!( + "Day 10, Part 01: {}", + device.signal_strengths().iter().sum::() + ); } #[cfg(feature = "part2")] { - println!("Day 10, Part 02: \n{}", rows.join("\n")); + println!("Day 10, Part 02: \n{}", device.output().join("\n")); } }