diff options
Diffstat (limited to '2022/src/day10.rs')
-rw-r--r-- | 2022/src/day10.rs | 82 |
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), +} |