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, add_next_start: Option, crt_pos: usize, } const CRT_WIDTH: usize = 40; const CRT_HEIGHT: usize = 6; const TOTAL_STEPS: usize = CRT_WIDTH * CRT_HEIGHT; fn run_steps(state: &mut State, cmd: &mut impl Iterator) { 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), }