diff --git a/samples/day10.txt b/samples/day10.txt new file mode 100644 index 0000000..94cd0a8 --- /dev/null +++ b/samples/day10.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 \ No newline at end of file diff --git a/src/bin/day10.rs b/src/bin/day10.rs new file mode 100644 index 0000000..63de3b3 --- /dev/null +++ b/src/bin/day10.rs @@ -0,0 +1,150 @@ +use std::str::FromStr; + +use aoc_2022::*; + +use color_eyre::{eyre::eyre, Report}; +use itertools::Itertools; +use tracing::{debug, info}; + +type Input = Vec; +type Output = i32; + +#[derive(Debug)] +enum Instruction { + Addx(i32), + Noop, +} + +impl FromStr for Instruction { + type Err = Report; + + fn from_str(s: &str) -> Result { + let split_s = s.split_ascii_whitespace().collect_vec(); + + match split_s[0] { + "noop" => Ok(Instruction::Noop), + "addx" => { + let value: i32 = split_s[1].parse()?; + Ok(Instruction::Addx(value)) + } + _ => Err(eyre!("Invalid instruction {}", split_s[0])), + } + } +} + +struct State { + cycle: i32, + register: i32, +} + +impl State { + fn new() -> Self { + Self { + cycle: 1, + register: 1, + } + } + + fn execute(&self, i: &Instruction) -> (State, i32) { + let next = match i { + Instruction::Addx(value) => State { + cycle: self.cycle + 2, + register: self.register + value, + }, + Instruction::Noop => State { + cycle: self.cycle + 1, + register: self.register, + }, + }; + // debug!("New state of CPU: cycle={}, register={}", next.cycle, next.register); + + let strength = if let Some(cycle) = + (self.cycle..next.cycle).find(|&c| c >= 20 && (c + 20) % 40 == 0) + { + // debug!( + // "Adding {} x {} = {} to sum", + // cycle, + // self.register, + // cycle * self.register + // ); + + cycle * self.register + } else { + 0 + }; + + (next, strength) + } + + fn execute_and_draw(&self, i: &Instruction, screen: &mut Vec>) -> State { + let next = match i { + Instruction::Addx(value) => State { + cycle: self.cycle + 2, + register: self.register + value, + }, + Instruction::Noop => State { + cycle: self.cycle + 1, + register: self.register, + }, + }; + // debug!("New state of CPU: cycle={}, register={}", next.cycle, next.register); + + // debug!("Checking: {:?} {:?}", i, (self.cycle..next.cycle)); + (self.cycle..next.cycle).for_each(|c| { + let idx = screen.len() - 1; + screen[idx].push( + if self.register - 1 <= (c - 1) % 40 && (c - 1) % 40 <= self.register + 1 { + '█' + } else { + ' ' + }, + ); + // debug!("{} ; {} <= {} <= {}", screen[idx].last().unwrap(), self.register - 1, c % 40, self.register + 1); + + if c % 40 == 0 { + screen.push(Vec::new()); + } + }); + + next + } +} + +struct Day10; +impl Solution for Day10 { + fn parse_input>(pathname: P) -> Input { + file_to_structs(pathname) + } + + fn part_1(input: &Input) -> Output { + input + .iter() + .fold((State::new(), 0), |(state, strength_sum), instruction| { + let (new_state, strength) = state.execute(instruction); + + (new_state, strength_sum + strength) + }) + .1 + } + + fn part_2(input: &Input) -> Output { + let mut screen: Vec> = vec![vec![]]; + + input.iter().fold(State::new(), |state, instruction| { + state.execute_and_draw(instruction, &mut screen) + }); + + info!( + "Screen:\n{}", + screen.iter().map(|line| line.iter().join("")).join("\n") + ); + + 0 + } +} + +fn main() -> Result<()> { + Day10::main() +} + +test_sample!(day_10, Day10, 13140, 1);