aboutsummaryrefslogtreecommitdiff
path: root/2022/src/day10.rs
diff options
context:
space:
mode:
Diffstat (limited to '2022/src/day10.rs')
-rw-r--r--2022/src/day10.rs82
1 files changed, 82 insertions, 0 deletions
diff --git a/2022/src/day10.rs b/2022/src/day10.rs
new file mode 100644
index 0000000..4c74444
--- /dev/null
+++ b/2022/src/day10.rs
@@ -0,0 +1,82 @@
+mod utils;
+use utils::{parse_num, parse_static, read_input};
+
+fn main() {
+ let input = read_input();
+
+ let mut cmds = input.lines().map(parse_cmd);
+ let mut state = State {
+ x: 1,
+ add_next: None,
+ add_next_start: None,
+ crt_pos: 0,
+ };
+
+ let mut acc = 0;
+ run_steps::<20>(&mut state, &mut cmds);
+ acc += state.x * 20;
+ for i in 1..=5 {
+ run_steps::<40>(&mut state, &mut cmds);
+ acc += state.x * (20 + (i * 40));
+ }
+
+ run_steps::<{ TOTAL_STEPS - 220 }>(&mut state, &mut cmds);
+
+ println!("Part 1: {}", acc);
+}
+
+struct State {
+ x: isize,
+ add_next: Option<isize>,
+ add_next_start: Option<isize>,
+ crt_pos: usize,
+}
+
+const CRT_WIDTH: usize = 40;
+const CRT_HEIGHT: usize = 6;
+const TOTAL_STEPS: usize = CRT_WIDTH * CRT_HEIGHT;
+
+fn run_steps<const N: usize>(state: &mut State, cmd: &mut impl Iterator<Item = Command>) {
+ for _ in 0..N {
+ if let Some(add) = state.add_next_start.take() {
+ state.x += add;
+ }
+
+ if (state.x - (state.crt_pos % CRT_WIDTH) as isize).abs() < 2 {
+ print!("█");
+ } else {
+ print!(" ");
+ }
+ state.crt_pos += 1;
+ if (state.crt_pos % CRT_WIDTH) == 0 {
+ println!();
+ }
+
+ if let Some(add) = state.add_next.take() {
+ state.add_next_start = Some(add);
+ } else {
+ match cmd.next() {
+ Some(Command::NoOp) => (),
+ Some(Command::AddX(add)) => state.add_next = Some(add),
+ None => (),
+ }
+ }
+ }
+}
+
+fn parse_cmd(cmd: &str) -> Command {
+ if cmd == "noop" {
+ Command::NoOp
+ } else {
+ let cmd = parse_static("addx ", cmd);
+ let (add, _) = parse_num(cmd);
+
+ Command::AddX(add)
+ }
+}
+
+#[derive(Debug)]
+enum Command {
+ NoOp,
+ AddX(isize),
+}