diff options
| author | Shivesh Mandalia <mail@shivesh.org> | 2022-12-30 17:20:17 +0000 |
|---|---|---|
| committer | Shivesh Mandalia <mail@shivesh.org> | 2022-12-30 17:20:17 +0000 |
| commit | 67a326403f50929586fc27bc845fc4a4290ec1ec (patch) | |
| tree | f58b204383bf86fdf6441b25b80cd15b5fa7d8a6 | |
| parent | e9b61b1519a9b1dc34944f269b6fc9b34715b278 (diff) | |
| download | advent_of_code_2022-67a326403f50929586fc27bc845fc4a4290ec1ec.tar.gz advent_of_code_2022-67a326403f50929586fc27bc845fc4a4290ec1ec.zip | |
complete day 10
| -rw-r--r-- | Cargo.lock | 15 | ||||
| -rw-r--r-- | Cargo.toml | 4 | ||||
| -rw-r--r-- | day10a/Cargo.toml | 10 | ||||
| -rw-r--r-- | day10a/examples/input.txt | 142 | ||||
| -rw-r--r-- | day10a/examples/test.txt | 146 | ||||
| -rw-r--r-- | day10a/src/main.rs | 303 | ||||
| -rw-r--r-- | day10b/Cargo.toml | 9 | ||||
| -rw-r--r-- | day10b/examples/input.txt | 142 | ||||
| -rw-r--r-- | day10b/examples/test.txt | 146 | ||||
| -rw-r--r-- | day10b/src/main.rs | 236 |
10 files changed, 1151 insertions, 2 deletions
@@ -217,6 +217,21 @@ dependencies = [ ] [[package]] +name = "day10a" +version = "0.1.0" +dependencies = [ + "clap", + "itertools", +] + +[[package]] +name = "day10b" +version = "0.1.0" +dependencies = [ + "clap", +] + +[[package]] name = "either" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -19,8 +19,8 @@ members = [ "day08b", "day09a", "day09b", - # "day10a", - # "day10b", + "day10a", + "day10b", # "day11a", # "day11b", # "day12a", diff --git a/day10a/Cargo.toml b/day10a/Cargo.toml new file mode 100644 index 0000000..c4bc0cb --- /dev/null +++ b/day10a/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "day10a" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap = { version = "3.2.20", features = ["derive"] } +itertools = "0.10.5" diff --git a/day10a/examples/input.txt b/day10a/examples/input.txt new file mode 100644 index 0000000..36431be --- /dev/null +++ b/day10a/examples/input.txt @@ -0,0 +1,142 @@ +addx 1 +addx 5 +noop +addx -1 +noop +noop +addx 6 +addx 15 +addx -9 +noop +addx -1 +addx 4 +addx 2 +addx -22 +addx 27 +addx -1 +addx 4 +noop +addx 1 +addx 2 +noop +noop +noop +noop +addx 1 +addx -33 +addx 2 +addx 5 +addx 2 +addx 3 +addx -2 +addx 7 +noop +addx -2 +addx -8 +addx 15 +addx 5 +noop +noop +addx -2 +addx 2 +noop +noop +addx 7 +addx -14 +noop +addx -2 +addx -17 +addx 5 +addx -4 +noop +addx 23 +addx -18 +noop +noop +noop +addx 28 +addx -18 +addx 4 +noop +noop +addx -5 +addx 1 +addx 10 +addx 2 +noop +noop +addx -30 +addx 33 +addx -32 +noop +noop +addx -2 +addx 6 +addx -2 +addx 4 +addx 3 +addx 19 +addx 10 +addx -5 +addx -16 +addx 3 +addx -2 +addx 17 +addx -19 +addx 11 +addx 2 +addx 9 +noop +addx -4 +addx -6 +addx -7 +addx -24 +noop +addx 7 +addx -2 +addx 5 +addx 2 +addx 3 +addx -2 +addx 2 +addx 5 +addx 2 +addx 7 +addx -2 +noop +addx 3 +addx -2 +addx 2 +addx 7 +noop +addx -2 +addx -34 +addx 1 +addx 1 +noop +noop +noop +addx 5 +noop +noop +addx 5 +addx -1 +noop +addx 6 +addx -1 +noop +addx 4 +addx 3 +addx 4 +addx -1 +addx 5 +noop +addx 5 +noop +noop +noop +noop +noop +addx 1 +noop +noop diff --git a/day10a/examples/test.txt b/day10a/examples/test.txt new file mode 100644 index 0000000..37ee8ee --- /dev/null +++ b/day10a/examples/test.txt @@ -0,0 +1,146 @@ +addx 15 +addx -11 +addx 6 +addx -3 +addx 5 +addx -1 +addx -8 +addx 13 +addx 4 +noop +addx -1 +addx 5 +addx -1 +addx 5 +addx -1 +addx 5 +addx -1 +addx 5 +addx -1 +addx -35 +addx 1 +addx 24 +addx -19 +addx 1 +addx 16 +addx -11 +noop +noop +addx 21 +addx -15 +noop +noop +addx -3 +addx 9 +addx 1 +addx -3 +addx 8 +addx 1 +addx 5 +noop +noop +noop +noop +noop +addx -36 +noop +addx 1 +addx 7 +noop +noop +noop +addx 2 +addx 6 +noop +noop +noop +noop +noop +addx 1 +noop +noop +addx 7 +addx 1 +noop +addx -13 +addx 13 +addx 7 +noop +addx 1 +addx -33 +noop +noop +noop +addx 2 +noop +noop +noop +addx 8 +noop +addx -1 +addx 2 +addx 1 +noop +addx 17 +addx -9 +addx 1 +addx 1 +addx -3 +addx 11 +noop +noop +addx 1 +noop +addx 1 +noop +noop +addx -13 +addx -19 +addx 1 +addx 3 +addx 26 +addx -30 +addx 12 +addx -1 +addx 3 +addx 1 +noop +noop +noop +addx -9 +addx 18 +addx 1 +addx 2 +noop +noop +addx 9 +noop +noop +noop +addx -1 +addx 2 +addx -37 +addx 1 +addx 3 +noop +addx 15 +addx -21 +addx 22 +addx -6 +addx 1 +noop +addx 2 +addx 1 +noop +addx -10 +noop +noop +addx 20 +addx 1 +addx 2 +addx 2 +addx -6 +addx -11 +noop +noop +noop diff --git a/day10a/src/main.rs b/day10a/src/main.rs new file mode 100644 index 0000000..1fba5c5 --- /dev/null +++ b/day10a/src/main.rs @@ -0,0 +1,303 @@ +/// --- Day 10: Cathode-Ray Tube --- +/// +/// You avoid the ropes, plunge into the river, and swim to shore. +/// +/// The Elves yell something about meeting back up with them upriver, but the river is too loud to +/// tell exactly what they're saying. They finish crossing the bridge and disappear from view. +/// +/// Situations like this must be why the Elves prioritized getting the communication system on your +/// handheld device working. You pull it out of your pack, but the amount of water slowly draining +/// from a big crack in its screen tells you it probably won't be of much immediate use. +/// +/// Unless, that is, you can design a replacement for the device's video system! It seems to be +/// some kind of cathode-ray tube screen and simple CPU that are both driven by a precise clock +/// circuit. The clock circuit ticks at a constant rate; each tick is called a cycle. +/// +/// Start by figuring out the signal being sent by the CPU. The CPU has a single register, X, +/// which starts with the value 1. It supports only two instructions: +/// +/// addx V takes two cycles to complete. After two cycles, the X register is increased by the +/// value V. (V can be negative.) +/// noop takes one cycle to complete. It has no other effect. +/// +/// The CPU uses these instructions in a program (your puzzle input) to, somehow, tell the screen +/// what to draw. +/// +/// Consider the following small program: +/// +/// noop +/// addx 3 +/// addx -5 +/// +/// Execution of this program proceeds as follows: +/// +/// At the start of the first cycle, the noop instruction begins execution. During the first +/// cycle, X is 1. After the first cycle, the noop instruction finishes execution, doing +/// nothing. +/// At the start of the second cycle, the addx 3 instruction begins execution. During the +/// second cycle, X is still 1. +/// During the third cycle, X is still 1. After the third cycle, the addx 3 instruction +/// finishes execution, setting X to 4. +/// At the start of the fourth cycle, the addx -5 instruction begins execution. During the +/// fourth cycle, X is still 4. +/// During the fifth cycle, X is still 4. After the fifth cycle, the addx -5 instruction +/// finishes execution, setting X to -1. +/// +/// Maybe you can learn something by looking at the value of the X register throughout execution. +/// For now, consider the signal strength (the cycle number multiplied by the value of the X +/// register) during the 20th cycle and every 40 cycles after that (that is, during the 20th, 60th, +/// 100th, 140th, 180th, and 220th cycles). +/// +/// For example, consider this larger program: +/// +/// ``` +/// addx 15 +/// addx -11 +/// addx 6 +/// addx -3 +/// addx 5 +/// addx -1 +/// addx -8 +/// addx 13 +/// addx 4 +/// noop +/// addx -1 +/// addx 5 +/// addx -1 +/// addx 5 +/// addx -1 +/// addx 5 +/// addx -1 +/// addx 5 +/// addx -1 +/// addx -35 +/// addx 1 +/// addx 24 +/// addx -19 +/// addx 1 +/// addx 16 +/// addx -11 +/// noop +/// noop +/// addx 21 +/// addx -15 +/// noop +/// noop +/// addx -3 +/// addx 9 +/// addx 1 +/// addx -3 +/// addx 8 +/// addx 1 +/// addx 5 +/// noop +/// noop +/// noop +/// noop +/// noop +/// addx -36 +/// noop +/// addx 1 +/// addx 7 +/// noop +/// noop +/// noop +/// addx 2 +/// addx 6 +/// noop +/// noop +/// noop +/// noop +/// noop +/// addx 1 +/// noop +/// noop +/// addx 7 +/// addx 1 +/// noop +/// addx -13 +/// addx 13 +/// addx 7 +/// noop +/// addx 1 +/// addx -33 +/// noop +/// noop +/// noop +/// addx 2 +/// noop +/// noop +/// noop +/// addx 8 +/// noop +/// addx -1 +/// addx 2 +/// addx 1 +/// noop +/// addx 17 +/// addx -9 +/// addx 1 +/// addx 1 +/// addx -3 +/// addx 11 +/// noop +/// noop +/// addx 1 +/// noop +/// addx 1 +/// noop +/// noop +/// addx -13 +/// addx -19 +/// addx 1 +/// addx 3 +/// addx 26 +/// addx -30 +/// addx 12 +/// addx -1 +/// addx 3 +/// addx 1 +/// noop +/// noop +/// noop +/// addx -9 +/// addx 18 +/// addx 1 +/// addx 2 +/// noop +/// noop +/// addx 9 +/// noop +/// noop +/// noop +/// addx -1 +/// addx 2 +/// addx -37 +/// addx 1 +/// addx 3 +/// noop +/// addx 15 +/// addx -21 +/// addx 22 +/// addx -6 +/// addx 1 +/// noop +/// addx 2 +/// addx 1 +/// noop +/// addx -10 +/// noop +/// noop +/// addx 20 +/// addx 1 +/// addx 2 +/// addx 2 +/// addx -6 +/// addx -11 +/// noop +/// noop +/// noop +/// ``` +/// +/// The interesting signal strengths can be determined as follows: +/// +/// During the 20th cycle, register X has the value 21, so the signal strength is 20 * 21 = +/// 420. (The 20th cycle occurs in the middle of the second addx -1, so the value of register X +/// is the starting value, 1, plus all of the other addx values up to that point: 1 + 15 - 11 + +/// 6 - 3 + 5 - 1 - 8 + 13 + 4 = 21.) +/// During the 60th cycle, register X has the value 19, so the signal strength is 60 * 19 = 1140. +/// During the 100th cycle, register X has the value 18, so the signal strength is 100 * 18 = 1800. +/// During the 140th cycle, register X has the value 21, so the signal strength is 140 * 21 = 2940. +/// During the 180th cycle, register X has the value 16, so the signal strength is 180 * 16 = 2880. +/// During the 220th cycle, register X has the value 18, so the signal strength is 220 * 18 = 3960. +/// +/// The sum of these signal strengths is 13140. +/// +/// Find the signal strength during the 20th, 60th, 100th, 140th, 180th, and 220th cycles. What is +/// the sum of these six signal strengths? +use clap::Parser; +use itertools::Itertools; + +use std::fs::File; +use std::io::prelude::*; +use std::io::BufReader; +use std::path::PathBuf; + +const FILEPATH: &'static str = "examples/input.txt"; +const XINIT: i32 = 1; +const INTERESTING_INIT: i32 = 20; +const INTERESTING_INCREMENT: i32 = 40; + +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about = None)] +struct Cli { + #[clap(short, long, default_value = FILEPATH)] + file: PathBuf, +} + +#[derive(Copy, Clone, Debug)] +enum Command { + Addx(i32), + Noop, +} + +#[derive(Copy, Clone, Debug)] +struct State { + x: i32, + cycle: u32, + res: i32, +} + +impl State { + fn new() -> Self { + State { + x: XINIT, + cycle: 0, + res: 0, + } + } + + fn process(&mut self) { + self.cycle += 1; + if (self.cycle as i32 + INTERESTING_INIT) % INTERESTING_INCREMENT == 0 { + self.res += self.cycle as i32 * self.x; + } + } +} + +impl Command { + fn parse(s: &str) -> Self { + let split_s = s.split_whitespace().collect_vec(); + match split_s.len() { + 1 => Command::Noop, + 2 => Command::Addx(split_s[1].parse::<i32>().unwrap()), + _ => panic!(), + } + } +} + +fn main() { + let args = Cli::parse(); + + let file = File::open(&args.file).unwrap(); + let reader = BufReader::new(file); + + let res = reader + .lines() + .map(|l| Command::parse(l.unwrap().as_str())) + .scan(State::new(), |state, command| { + state.process(); + match command { + Command::Noop => (), + Command::Addx(value) => { + state.process(); + state.x += value; + } + }; + Some(state.res) + }) + .last() + .unwrap(); + + println!("{res:?}"); +} diff --git a/day10b/Cargo.toml b/day10b/Cargo.toml new file mode 100644 index 0000000..c71a33d --- /dev/null +++ b/day10b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day10b" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap = { version = "3.2.20", features = ["derive"] } diff --git a/day10b/examples/input.txt b/day10b/examples/input.txt new file mode 100644 index 0000000..36431be --- /dev/null +++ b/day10b/examples/input.txt @@ -0,0 +1,142 @@ +addx 1 +addx 5 +noop +addx -1 +noop +noop +addx 6 +addx 15 +addx -9 +noop +addx -1 +addx 4 +addx 2 +addx -22 +addx 27 +addx -1 +addx 4 +noop +addx 1 +addx 2 +noop +noop +noop +noop +addx 1 +addx -33 +addx 2 +addx 5 +addx 2 +addx 3 +addx -2 +addx 7 +noop +addx -2 +addx -8 +addx 15 +addx 5 +noop +noop +addx -2 +addx 2 +noop +noop +addx 7 +addx -14 +noop +addx -2 +addx -17 +addx 5 +addx -4 +noop +addx 23 +addx -18 +noop +noop +noop +addx 28 +addx -18 +addx 4 +noop +noop +addx -5 +addx 1 +addx 10 +addx 2 +noop +noop +addx -30 +addx 33 +addx -32 +noop +noop +addx -2 +addx 6 +addx -2 +addx 4 +addx 3 +addx 19 +addx 10 +addx -5 +addx -16 +addx 3 +addx -2 +addx 17 +addx -19 +addx 11 +addx 2 +addx 9 +noop +addx -4 +addx -6 +addx -7 +addx -24 +noop +addx 7 +addx -2 +addx 5 +addx 2 +addx 3 +addx -2 +addx 2 +addx 5 +addx 2 +addx 7 +addx -2 +noop +addx 3 +addx -2 +addx 2 +addx 7 +noop +addx -2 +addx -34 +addx 1 +addx 1 +noop +noop +noop +addx 5 +noop +noop +addx 5 +addx -1 +noop +addx 6 +addx -1 +noop +addx 4 +addx 3 +addx 4 +addx -1 +addx 5 +noop +addx 5 +noop +noop +noop +noop +noop +addx 1 +noop +noop diff --git a/day10b/examples/test.txt b/day10b/examples/test.txt new file mode 100644 index 0000000..37ee8ee --- /dev/null +++ b/day10b/examples/test.txt @@ -0,0 +1,146 @@ +addx 15 +addx -11 +addx 6 +addx -3 +addx 5 +addx -1 +addx -8 +addx 13 +addx 4 +noop +addx -1 +addx 5 +addx -1 +addx 5 +addx -1 +addx 5 +addx -1 +addx 5 +addx -1 +addx -35 +addx 1 +addx 24 +addx -19 +addx 1 +addx 16 +addx -11 +noop +noop +addx 21 +addx -15 +noop +noop +addx -3 +addx 9 +addx 1 +addx -3 +addx 8 +addx 1 +addx 5 +noop +noop +noop +noop +noop +addx -36 +noop +addx 1 +addx 7 +noop +noop +noop +addx 2 +addx 6 +noop +noop +noop +noop +noop +addx 1 +noop +noop +addx 7 +addx 1 +noop +addx -13 +addx 13 +addx 7 +noop +addx 1 +addx -33 +noop +noop +noop +addx 2 +noop +noop +noop +addx 8 +noop +addx -1 +addx 2 +addx 1 +noop +addx 17 +addx -9 +addx 1 +addx 1 +addx -3 +addx 11 +noop +noop +addx 1 +noop +addx 1 +noop +noop +addx -13 +addx -19 +addx 1 +addx 3 +addx 26 +addx -30 +addx 12 +addx -1 +addx 3 +addx 1 +noop +noop +noop +addx -9 +addx 18 +addx 1 +addx 2 +noop +noop +addx 9 +noop +noop +noop +addx -1 +addx 2 +addx -37 +addx 1 +addx 3 +noop +addx 15 +addx -21 +addx 22 +addx -6 +addx 1 +noop +addx 2 +addx 1 +noop +addx -10 +noop +noop +addx 20 +addx 1 +addx 2 +addx 2 +addx -6 +addx -11 +noop +noop +noop diff --git a/day10b/src/main.rs b/day10b/src/main.rs new file mode 100644 index 0000000..5094ae4 --- /dev/null +++ b/day10b/src/main.rs @@ -0,0 +1,236 @@ +/// --- Part Two --- +/// +/// It seems like the X register controls the horizontal position of a sprite. Specifically, the +/// sprite is 3 pixels wide, and the X register sets the horizontal position of the middle of that +/// sprite. (In this system, there is no such thing as "vertical position": if the sprite's +/// horizontal position puts its pixels where the CRT is currently drawing, then those pixels will +/// be drawn.) +/// +/// You count the pixels on the CRT: 40 wide and 6 high. This CRT screen draws the top row of +/// pixels left-to-right, then the row below that, and so on. The left-most pixel in each row is +/// in position 0, and the right-most pixel in each row is in position 39. +/// +/// Like the CPU, the CRT is tied closely to the clock circuit: the CRT draws a single pixel during +/// each cycle. Representing each pixel of the screen as a #, here are the cycles during which the +/// first and last pixel in each row are drawn: +/// +/// ``` +/// Cycle 1 -> ######################################## <- Cycle 40 +/// Cycle 41 -> ######################################## <- Cycle 80 +/// Cycle 81 -> ######################################## <- Cycle 120 +/// Cycle 121 -> ######################################## <- Cycle 160 +/// Cycle 161 -> ######################################## <- Cycle 200 +/// Cycle 201 -> ######################################## <- Cycle 240 +/// ``` +/// +/// So, by carefully timing the CPU instructions and the CRT drawing operations, you should be able +/// to determine whether the sprite is visible the instant each pixel is drawn. If the sprite is +/// positioned such that one of its three pixels is the pixel currently being drawn, the screen +/// produces a lit pixel (#); otherwise, the screen leaves the pixel dark (.). +/// +/// The first few pixels from the larger example above are drawn as follows: +/// +/// ``` +/// Sprite position: ###..................................... +/// +/// Start cycle 1: begin executing addx 15 +/// During cycle 1: CRT draws pixel in position 0 +/// Current CRT row: # +/// +/// During cycle 2: CRT draws pixel in position 1 +/// Current CRT row: ## +/// End of cycle 2: finish executing addx 15 (Register X is now 16) +/// Sprite position: ...............###...................... +/// +/// Start cycle 3: begin executing addx -11 +/// During cycle 3: CRT draws pixel in position 2 +/// Current CRT row: ##. +/// +/// During cycle 4: CRT draws pixel in position 3 +/// Current CRT row: ##.. +/// End of cycle 4: finish executing addx -11 (Register X is now 5) +/// Sprite position: ....###................................. +/// +/// Start cycle 5: begin executing addx 6 +/// During cycle 5: CRT draws pixel in position 4 +/// Current CRT row: ##..# +/// +/// During cycle 6: CRT draws pixel in position 5 +/// Current CRT row: ##..## +/// End of cycle 6: finish executing addx 6 (Register X is now 11) +/// Sprite position: ..........###........................... +/// +/// Start cycle 7: begin executing addx -3 +/// During cycle 7: CRT draws pixel in position 6 +/// Current CRT row: ##..##. +/// +/// During cycle 8: CRT draws pixel in position 7 +/// Current CRT row: ##..##.. +/// End of cycle 8: finish executing addx -3 (Register X is now 8) +/// Sprite position: .......###.............................. +/// +/// Start cycle 9: begin executing addx 5 +/// During cycle 9: CRT draws pixel in position 8 +/// Current CRT row: ##..##..# +/// +/// During cycle 10: CRT draws pixel in position 9 +/// Current CRT row: ##..##..## +/// End of cycle 10: finish executing addx 5 (Register X is now 13) +/// Sprite position: ............###......................... +/// +/// Start cycle 11: begin executing addx -1 +/// During cycle 11: CRT draws pixel in position 10 +/// Current CRT row: ##..##..##. +/// +/// During cycle 12: CRT draws pixel in position 11 +/// Current CRT row: ##..##..##.. +/// End of cycle 12: finish executing addx -1 (Register X is now 12) +/// Sprite position: ...........###.......................... +/// +/// Start cycle 13: begin executing addx -8 +/// During cycle 13: CRT draws pixel in position 12 +/// Current CRT row: ##..##..##..# +/// +/// During cycle 14: CRT draws pixel in position 13 +/// Current CRT row: ##..##..##..## +/// End of cycle 14: finish executing addx -8 (Register X is now 4) +/// Sprite position: ...###.................................. +/// +/// Start cycle 15: begin executing addx 13 +/// During cycle 15: CRT draws pixel in position 14 +/// Current CRT row: ##..##..##..##. +/// +/// During cycle 16: CRT draws pixel in position 15 +/// Current CRT row: ##..##..##..##.. +/// End of cycle 16: finish executing addx 13 (Register X is now 17) +/// Sprite position: ................###..................... +/// +/// Start cycle 17: begin executing addx 4 +/// During cycle 17: CRT draws pixel in position 16 +/// Current CRT row: ##..##..##..##..# +/// +/// During cycle 18: CRT draws pixel in position 17 +/// Current CRT row: ##..##..##..##..## +/// End of cycle 18: finish executing addx 4 (Register X is now 21) +/// Sprite position: ....................###................. +/// +/// Start cycle 19: begin executing noop +/// During cycle 19: CRT draws pixel in position 18 +/// Current CRT row: ##..##..##..##..##. +/// End of cycle 19: finish executing noop +/// +/// Start cycle 20: begin executing addx -1 +/// During cycle 20: CRT draws pixel in position 19 +/// Current CRT row: ##..##..##..##..##.. +/// +/// During cycle 21: CRT draws pixel in position 20 +/// Current CRT row: ##..##..##..##..##..# +/// End of cycle 21: finish executing addx -1 (Register X is now 20) +/// Sprite position: ...................###.................. +/// ``` +/// +/// Allowing the program to run to completion causes the CRT to produce the following image: +/// +/// ``` +/// ##..##..##..##..##..##..##..##..##..##.. +/// ###...###...###...###...###...###...###. +/// ####....####....####....####....####.... +/// #####.....#####.....#####.....#####..... +/// ######......######......######......#### +/// #######.......#######.......#######..... +/// ``` +/// +/// Render the image given by your program. What eight capital letters appear on your CRT? +use clap::Parser; + +use std::fmt::Write; +use std::fs::File; +use std::io::prelude::*; +use std::io::BufReader; +use std::path::PathBuf; + +const FILEPATH: &'static str = "examples/input.txt"; +const XINIT: i32 = 1; +const SPRITE_WIDTH: u8 = 3; +const CRT_WIDTH: i32 = 40; + +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about = None)] +struct Cli { + #[clap(short, long, default_value = FILEPATH)] + file: PathBuf, +} + +#[derive(Copy, Clone, Debug)] +enum Command { + Addx(i32), + Noop, +} + +#[derive(Clone, Debug)] +struct State { + x: i32, + cycle: u32, + res: String, +} + +impl State { + fn new() -> Self { + State { + x: XINIT, + cycle: 0, + res: String::new(), + } + } + + fn process(&mut self) { + self.cycle += 1; + let pos = (self.cycle as i32 - 1) % CRT_WIDTH; + if (pos + 1) < self.x || pos + 1 >= (self.x + SPRITE_WIDTH as i32) { + self.res += " "; + } else { + self.res += "█"; + } + if self.cycle as i32 % CRT_WIDTH == 0 { + writeln!(&mut self.res).unwrap(); + } + } +} + +impl Command { + fn parse(s: &str) -> Self { + let split_s = s.split_whitespace().collect::<Vec<&str>>(); + match split_s.len() { + 1 => Command::Noop, + 2 => Command::Addx(split_s[1].parse::<i32>().unwrap()), + _ => panic!(), + } + } +} + +fn main() { + let args = Cli::parse(); + + let file = File::open(&args.file).unwrap(); + let reader = BufReader::new(file); + + let res = reader + .lines() + .map(|l| Command::parse(l.unwrap().as_str())) + .scan(State::new(), |state, command| { + state.process(); + match command { + Command::Noop => (), + Command::Addx(value) => { + state.process(); + state.x += value; + } + }; + Some(state.res.clone()) + }) + .last() + .unwrap(); + + // "ZGCJZJFL" + println!("{res}"); +} |
