summaryrefslogtreecommitdiffstats
path: root/day10b
diff options
context:
space:
mode:
authorShivesh Mandalia <mail@shivesh.org>2022-12-30 17:20:17 +0000
committerShivesh Mandalia <mail@shivesh.org>2022-12-30 17:20:17 +0000
commit67a326403f50929586fc27bc845fc4a4290ec1ec (patch)
treef58b204383bf86fdf6441b25b80cd15b5fa7d8a6 /day10b
parente9b61b1519a9b1dc34944f269b6fc9b34715b278 (diff)
downloadadvent_of_code_2022-67a326403f50929586fc27bc845fc4a4290ec1ec.tar.gz
advent_of_code_2022-67a326403f50929586fc27bc845fc4a4290ec1ec.zip
complete day 10
Diffstat (limited to 'day10b')
-rw-r--r--day10b/Cargo.toml9
-rw-r--r--day10b/examples/input.txt142
-rw-r--r--day10b/examples/test.txt146
-rw-r--r--day10b/src/main.rs236
4 files changed, 533 insertions, 0 deletions
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}");
+}