day10 part 2.

This commit is contained in:
Gabe Venberg 2023-12-20 13:53:17 -06:00
parent 711dbb63d2
commit 79657a2f91
8 changed files with 348 additions and 23 deletions

118
days/day10/src/crt.rs Normal file
View file

@ -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<usize> 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<usize> 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
]
]
}
)
}
}

View file

@ -1,5 +1,6 @@
use std::{collections::VecDeque, fmt}; use std::{collections::VecDeque, fmt};
use crate::crt::Crt;
use crate::parse::*; use crate::parse::*;
pub struct Machine { pub struct Machine {
@ -7,6 +8,7 @@ pub struct Machine {
current_instruction: Option<(Instruction, usize)>, current_instruction: Option<(Instruction, usize)>,
cycle: usize, cycle: usize,
x: i32, x: i32,
pub crt: Crt,
} }
impl Machine { impl Machine {
@ -16,16 +18,19 @@ impl Machine {
current_instruction: None, current_instruction: None,
cycle: 0, cycle: 0,
x: 1, x: 1,
crt: Crt::default(),
}; };
res.fetch_next_instruction(); res.fetch_next_instruction();
res res
} }
pub fn step(&mut self) -> bool { pub fn step(&mut self) -> (bool, i32) {
if self.current_instruction.is_none() { 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(); let (instruction, cycles_left) = self.current_instruction.as_mut().unwrap();
*cycles_left -= 1; *cycles_left -= 1;
if *cycles_left == 0 { if *cycles_left == 0 {
@ -37,7 +42,8 @@ impl Machine {
}; };
self.cycle += 1; self.cycle += 1;
true self.crt.draw_pixel(x, self.cycle);
(true, x)
} }
fn fetch_next_instruction(&mut self) { fn fetch_next_instruction(&mut self) {
@ -47,17 +53,11 @@ impl Machine {
//returns the signal strength during the middle of the 20th cycle. //returns the signal strength during the middle of the 20th cycle.
pub fn step20(&mut self) -> i32 { pub fn step20(&mut self) -> i32 {
for _ in 0..19 { for _ in 0..19 {
if !self.step() { if !self.step().0 {
break; break;
} }
} }
let ret = self.x*(self.cycle as i32 +1); self.step().1 * self.cycle as i32
self.step();
ret
}
pub fn signal_strength(&self) -> i32 {
self.x * (self.cycle as i32)
} }
} }
@ -78,6 +78,205 @@ impl fmt::Debug for Machine {
mod tests { mod tests {
use super::*; 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] #[test]
fn test_machine() { fn test_machine() {
let input = vec![ let input = vec![

View file

@ -2,14 +2,15 @@ mod part1;
mod part2; mod part2;
mod parse; mod parse;
mod machine; mod machine;
mod crt;
fn main() { fn main() {
let input = include_str!("./input.txt"); let input = include_str!("./input.txt");
let structured_input = parse::parse(input); let structured_input = parse::parse(input);
println!("Part One"); println!("Part One");
println!("Result: {}", part1::part1(structured_input)); println!("Result: {}", part1::part1(structured_input.clone()));
println!("Part Two"); println!("Part Two");
println!("Result: {}", part2::part2()); println!("Result:\n{}", part2::part2(structured_input.clone()));
} }

View file

@ -1,7 +1,11 @@
use crate::parse::*; use std::collections::VecDeque;
pub fn part2() -> usize { use crate::{crt::Crt, parse::*, machine::Machine};
unimplemented!()
pub fn part2(input: VecDeque<Instruction>) -> Crt {
let mut machine = Machine::load_program(input);
while machine.step().0 {};
machine.crt
} }
#[cfg(test)] #[cfg(test)]

View file

@ -7,8 +7,8 @@ fn main() {
let structured_input = parse::parse(input); let structured_input = parse::parse(input);
println!("Part One"); println!("Part One");
println!("Result: {}", part1::part1()); println!("Result: {}", part1::part1(&structured_input));
println!("Part Two"); println!("Part Two");
println!("Result: {}", part2::part2()); println!("Result: {}", part2::part2(&structured_input));
} }

View file

@ -1,4 +1,6 @@
pub fn parse(input: &str) -> usize { pub type StructuredInput = usize;
pub fn parse(input: &str) -> StructuredInput {
unimplemented!() unimplemented!()
} }

View file

@ -1,5 +1,6 @@
use crate::parse::* use crate::parse::*;
pub fn part1() -> usize {
pub fn part1(input: &StructuredInput) -> usize {
unimplemented!() unimplemented!()
} }

View file

@ -1,6 +1,6 @@
use crate::parse::* use crate::parse::*;
pub fn part2() -> usize { pub fn part2(input: &StructuredInput) -> usize {
unimplemented!() unimplemented!()
} }