diff --git a/days/day10/src/crt.rs b/days/day10/src/crt.rs new file mode 100644 index 0000000..caf8b4a --- /dev/null +++ b/days/day10/src/crt.rs @@ -0,0 +1,118 @@ +use std::fmt::Display; + +use crate::machine::Machine; + +#[derive(Debug, PartialEq, Eq)] +pub struct Crt { + pub screen: [[bool; 40]; 6], +} + +impl Crt { + pub fn draw_pixel(&mut self, sprite_pos: i32, cycle: usize) { + let x_coord = (cycle - 1) % self.screen[0].len(); + if sprite_pos.abs_diff(x_coord as i32) <= 1 { + self[cycle] = true + } + } +} + +impl Default for Crt { + fn default() -> Self { + Self { + screen: [[false; 40]; 6], + } + } +} + +impl Display for Crt { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for line in self.screen { + for char in line { + if char { + write!(f, "#")?; + } else { + write!(f, ".")?; + } + } + writeln!(f)?; + } + Ok(()) + } +} + +impl std::ops::Index for Crt { + type Output = bool; + + fn index(&self, index: usize) -> &Self::Output { + let index = index - 1; + let x = index % self.screen[0].len(); + let y = index / self.screen[0].len(); + &self.screen[y][x] + } +} + +impl std::ops::IndexMut for Crt { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + let index = index - 1; + let x = index % self.screen[0].len(); + let y = index / self.screen[0].len(); + &mut self.screen[y][x] + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_index() { + let mut input = Crt::default(); + input[1] = true; + input[40] = true; + input[41] = true; + println!("{}", input); + assert_eq!( + input, + Crt { + screen: [ + [ + true, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, true + ], + [ + true, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false + ], + [ + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false + ], + [ + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false + ], + [ + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false + ], + [ + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false + ] + ] + } + ) + } +} diff --git a/days/day10/src/machine.rs b/days/day10/src/machine.rs index 9b2fbbe..b148ee9 100644 --- a/days/day10/src/machine.rs +++ b/days/day10/src/machine.rs @@ -1,5 +1,6 @@ use std::{collections::VecDeque, fmt}; +use crate::crt::Crt; use crate::parse::*; pub struct Machine { @@ -7,6 +8,7 @@ pub struct Machine { current_instruction: Option<(Instruction, usize)>, cycle: usize, x: i32, + pub crt: Crt, } impl Machine { @@ -16,16 +18,19 @@ impl Machine { current_instruction: None, cycle: 0, x: 1, + crt: Crt::default(), }; res.fetch_next_instruction(); res } - pub fn step(&mut self) -> bool { + pub fn step(&mut self) -> (bool, i32) { if self.current_instruction.is_none() { - return false; + return (false, self.x); } + //we return x as it was at the beginning of the cycle. + let x = self.x; let (instruction, cycles_left) = self.current_instruction.as_mut().unwrap(); *cycles_left -= 1; if *cycles_left == 0 { @@ -37,7 +42,8 @@ impl Machine { }; self.cycle += 1; - true + self.crt.draw_pixel(x, self.cycle); + (true, x) } fn fetch_next_instruction(&mut self) { @@ -47,17 +53,11 @@ impl Machine { //returns the signal strength during the middle of the 20th cycle. pub fn step20(&mut self) -> i32 { for _ in 0..19 { - if !self.step() { + if !self.step().0 { break; } } - let ret = self.x*(self.cycle as i32 +1); - self.step(); - ret - } - - pub fn signal_strength(&self) -> i32 { - self.x * (self.cycle as i32) + self.step().1 * self.cycle as i32 } } @@ -78,6 +78,205 @@ impl fmt::Debug for Machine { mod tests { use super::*; + #[test] + fn test_screen() { + let input = vec![ + Instruction::Addx(15), + Instruction::Addx(-11), + Instruction::Addx(6), + Instruction::Addx(-3), + Instruction::Addx(5), + Instruction::Addx(-1), + Instruction::Addx(-8), + Instruction::Addx(13), + Instruction::Addx(4), + Instruction::NoOp, + Instruction::Addx(-1), + Instruction::Addx(5), + Instruction::Addx(-1), + Instruction::Addx(5), + Instruction::Addx(-1), + Instruction::Addx(5), + Instruction::Addx(-1), + Instruction::Addx(5), + Instruction::Addx(-1), + Instruction::Addx(-35), + Instruction::Addx(1), + Instruction::Addx(24), + Instruction::Addx(-19), + Instruction::Addx(1), + Instruction::Addx(16), + Instruction::Addx(-11), + Instruction::NoOp, + Instruction::NoOp, + Instruction::Addx(21), + Instruction::Addx(-15), + Instruction::NoOp, + Instruction::NoOp, + Instruction::Addx(-3), + Instruction::Addx(9), + Instruction::Addx(1), + Instruction::Addx(-3), + Instruction::Addx(8), + Instruction::Addx(1), + Instruction::Addx(5), + Instruction::NoOp, + Instruction::NoOp, + Instruction::NoOp, + Instruction::NoOp, + Instruction::NoOp, + Instruction::Addx(-36), + Instruction::NoOp, + Instruction::Addx(1), + Instruction::Addx(7), + Instruction::NoOp, + Instruction::NoOp, + Instruction::NoOp, + Instruction::Addx(2), + Instruction::Addx(6), + Instruction::NoOp, + Instruction::NoOp, + Instruction::NoOp, + Instruction::NoOp, + Instruction::NoOp, + Instruction::Addx(1), + Instruction::NoOp, + Instruction::NoOp, + Instruction::Addx(7), + Instruction::Addx(1), + Instruction::NoOp, + Instruction::Addx(-13), + Instruction::Addx(13), + Instruction::Addx(7), + Instruction::NoOp, + Instruction::Addx(1), + Instruction::Addx(-33), + Instruction::NoOp, + Instruction::NoOp, + Instruction::NoOp, + Instruction::Addx(2), + Instruction::NoOp, + Instruction::NoOp, + Instruction::NoOp, + Instruction::Addx(8), + Instruction::NoOp, + Instruction::Addx(-1), + Instruction::Addx(2), + Instruction::Addx(1), + Instruction::NoOp, + Instruction::Addx(17), + Instruction::Addx(-9), + Instruction::Addx(1), + Instruction::Addx(1), + Instruction::Addx(-3), + Instruction::Addx(11), + Instruction::NoOp, + Instruction::NoOp, + Instruction::Addx(1), + Instruction::NoOp, + Instruction::Addx(1), + Instruction::NoOp, + Instruction::NoOp, + Instruction::Addx(-13), + Instruction::Addx(-19), + Instruction::Addx(1), + Instruction::Addx(3), + Instruction::Addx(26), + Instruction::Addx(-30), + Instruction::Addx(12), + Instruction::Addx(-1), + Instruction::Addx(3), + Instruction::Addx(1), + Instruction::NoOp, + Instruction::NoOp, + Instruction::NoOp, + Instruction::Addx(-9), + Instruction::Addx(18), + Instruction::Addx(1), + Instruction::Addx(2), + Instruction::NoOp, + Instruction::NoOp, + Instruction::Addx(9), + Instruction::NoOp, + Instruction::NoOp, + Instruction::NoOp, + Instruction::Addx(-1), + Instruction::Addx(2), + Instruction::Addx(-37), + Instruction::Addx(1), + Instruction::Addx(3), + Instruction::NoOp, + Instruction::Addx(15), + Instruction::Addx(-21), + Instruction::Addx(22), + Instruction::Addx(-6), + Instruction::Addx(1), + Instruction::NoOp, + Instruction::Addx(2), + Instruction::Addx(1), + Instruction::NoOp, + Instruction::Addx(-10), + Instruction::NoOp, + Instruction::NoOp, + Instruction::Addx(20), + Instruction::Addx(1), + Instruction::Addx(2), + Instruction::Addx(2), + Instruction::Addx(-6), + Instruction::Addx(-11), + Instruction::NoOp, + Instruction::NoOp, + Instruction::NoOp, + ]; + let mut machine = Machine::load_program(input.into()); + //step till we cant anymore. + while machine.step().0 {} + println!("{}", machine.crt); + assert_eq!( + machine.crt, + Crt { + screen: [ + [ + true, true, false, false, true, true, false, false, true, true, false, + false, true, true, false, false, true, true, false, false, true, true, + false, false, true, true, false, false, true, true, false, false, true, + true, false, false, true, true, false, false + ], + [ + true, true, true, false, false, false, true, true, true, false, false, + false, true, true, true, false, false, false, true, true, true, false, + false, false, true, true, true, false, false, false, true, true, true, + false, false, false, true, true, true, false + ], + [ + true, true, true, true, false, false, false, false, true, true, true, true, + false, false, false, false, true, true, true, true, false, false, false, + false, true, true, true, true, false, false, false, false, true, true, + true, true, false, false, false, false + ], + [ + true, true, true, true, true, false, false, false, false, false, true, + true, true, true, true, false, false, false, false, false, true, true, + true, true, true, false, false, false, false, false, true, true, true, + true, true, false, false, false, false, false + ], + [ + true, true, true, true, true, true, false, false, false, false, false, + false, true, true, true, true, true, true, false, false, false, false, + false, false, true, true, true, true, true, true, false, false, false, + false, false, false, true, true, true, true + ], + [ + true, true, true, true, true, true, true, false, false, false, false, + false, false, false, true, true, true, true, true, true, true, false, + false, false, false, false, false, false, true, true, true, true, true, + true, true, false, false, false, false, false + ] + ] + } + ) + } + #[test] fn test_machine() { let input = vec![ diff --git a/days/day10/src/main.rs b/days/day10/src/main.rs index 72815fb..b82e7ad 100644 --- a/days/day10/src/main.rs +++ b/days/day10/src/main.rs @@ -2,14 +2,15 @@ mod part1; mod part2; mod parse; mod machine; +mod crt; fn main() { let input = include_str!("./input.txt"); let structured_input = parse::parse(input); println!("Part One"); - println!("Result: {}", part1::part1(structured_input)); + println!("Result: {}", part1::part1(structured_input.clone())); println!("Part Two"); - println!("Result: {}", part2::part2()); + println!("Result:\n{}", part2::part2(structured_input.clone())); } diff --git a/days/day10/src/part2.rs b/days/day10/src/part2.rs index 419e697..5c43139 100644 --- a/days/day10/src/part2.rs +++ b/days/day10/src/part2.rs @@ -1,7 +1,11 @@ -use crate::parse::*; +use std::collections::VecDeque; -pub fn part2() -> usize { - unimplemented!() +use crate::{crt::Crt, parse::*, machine::Machine}; + +pub fn part2(input: VecDeque) -> Crt { + let mut machine = Machine::load_program(input); + while machine.step().0 {}; + machine.crt } #[cfg(test)] diff --git a/template/src/main.rs b/template/src/main.rs index e282b24..456385c 100644 --- a/template/src/main.rs +++ b/template/src/main.rs @@ -7,8 +7,8 @@ fn main() { let structured_input = parse::parse(input); println!("Part One"); - println!("Result: {}", part1::part1()); + println!("Result: {}", part1::part1(&structured_input)); println!("Part Two"); - println!("Result: {}", part2::part2()); + println!("Result: {}", part2::part2(&structured_input)); } diff --git a/template/src/parse.rs b/template/src/parse.rs index 29de48b..ed7984c 100644 --- a/template/src/parse.rs +++ b/template/src/parse.rs @@ -1,4 +1,6 @@ -pub fn parse(input: &str) -> usize { +pub type StructuredInput = usize; + +pub fn parse(input: &str) -> StructuredInput { unimplemented!() } diff --git a/template/src/part1.rs b/template/src/part1.rs index dd46fd2..bcd1611 100644 --- a/template/src/part1.rs +++ b/template/src/part1.rs @@ -1,5 +1,6 @@ -use crate::parse::* -pub fn part1() -> usize { +use crate::parse::*; + +pub fn part1(input: &StructuredInput) -> usize { unimplemented!() } diff --git a/template/src/part2.rs b/template/src/part2.rs index 6d129e2..687e0cf 100644 --- a/template/src/part2.rs +++ b/template/src/part2.rs @@ -1,6 +1,6 @@ -use crate::parse::* +use crate::parse::*; -pub fn part2() -> usize { +pub fn part2(input: &StructuredInput) -> usize { unimplemented!() }