From 9c8c4505d404391ec571a0fce63b7ea7144e8854 Mon Sep 17 00:00:00 2001 From: Tobias Marschner Date: Wed, 21 Feb 2024 22:51:27 +0100 Subject: [PATCH] Solution for 2022/day10-part2 --- 2022/day10-part2/Cargo.toml | 8 ++++ 2022/day10-part2/src/main.rs | 87 ++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 2022/day10-part2/Cargo.toml create mode 100644 2022/day10-part2/src/main.rs diff --git a/2022/day10-part2/Cargo.toml b/2022/day10-part2/Cargo.toml new file mode 100644 index 0000000..f2c3859 --- /dev/null +++ b/2022/day10-part2/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day10-part2" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/2022/day10-part2/src/main.rs b/2022/day10-part2/src/main.rs new file mode 100644 index 0000000..f0eed26 --- /dev/null +++ b/2022/day10-part2/src/main.rs @@ -0,0 +1,87 @@ +struct Crt { + screen: [bool; 40 * 6], +} + +impl Crt { + fn new() -> Crt { + Crt { + screen: [false; 40 * 6], + } + } + + fn process_cycle(&mut self, cycle: usize, x: i32) { + // Split cycle into corresponding line and column. + let col = (cycle as i32) % 40; + + // Set the current pixel if the current column and the + // sprite painted by the current x value overlap. + self.screen[cycle] = (x - 1) == col || x == col || (x + 1) == col; + } + + fn print(&self) { + for (i, x) in self.screen.iter().enumerate() { + // Print `##` or `. ` depending on bool value. + print!("{}", if *x { "##" } else { ". " }); + // Print a newline every 40 characters. + if (i + 1) % 40 == 0 { + println!(); + } + } + } +} + +fn main() { + // Use command line arguments to specify the input filename. + let args: Vec = std::env::args().collect(); + if args.len() < 2 { + panic!("Usage: ./main \nNo input file provided. Exiting."); + } + + // Next, read the contents of the input file into a string for easier processing. + let input = std::fs::read_to_string(&args[1]).expect("Error opening file"); + // Line-by-line processing is easiest. + let input = input.lines(); + + // --- TASK BEGIN --- + + // Keep track of the current value of X for all the instructions. + // We'll use one massive vector for that purpose. + let mut x_over_time: Vec = Vec::with_capacity(512); + + // Keep track of the actual x as well. + let mut x = 1; + + // Then, process line-by-line. + for line in input { + // Split by space. + let line: Vec<_> = line.split(' ').collect(); + + // Differentiate by instruction + match line[0] { + "noop" => { + // Nothing changes. + x_over_time.push(x); + } + "addx" => { + // Addition is complete *after* two cycles. + // So during those two cycles x has the old value still. + x_over_time.push(x); + x_over_time.push(x); + // Of course, afterwards the value of x is updated. + x += line[1].parse::().unwrap(); + } + _ => (), + } + } + + // Reserve the CRT and ... + let mut crt = Crt::new(); + + // ... iterate over all cycles to compute what would be shown on the screen. + for (i, x) in x_over_time.iter().enumerate() { + crt.process_cycle(i, *x); + } + + // Finally, print said screen. + crt.print(); +}