Refactored computer
This commit is contained in:
parent
d42491f71a
commit
dfb8421dec
133
src/day10/mod.rs
133
src/day10/mod.rs
@ -27,67 +27,100 @@ impl Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run() {
|
struct Puter {
|
||||||
|
register_x: (i32, i32),
|
||||||
|
cycle: usize,
|
||||||
|
pixel_row: [bool; Puter::LINE_WIDTH],
|
||||||
|
rows: Vec<String>,
|
||||||
|
cycles_processing_left: usize,
|
||||||
|
|
||||||
|
signal_strengths: Vec<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Puter {
|
||||||
const LINE_WIDTH: usize = 40;
|
const LINE_WIDTH: usize = 40;
|
||||||
const SPRITE_WIDTH: usize = 3;
|
const SPRITE_WIDTH: usize = 3;
|
||||||
const SPRITE_WIDTH_HALF: usize = SPRITE_WIDTH / 2;
|
const SPRITE_WIDTH_HALF: usize = Puter::SPRITE_WIDTH / 2;
|
||||||
|
|
||||||
let input = read("10");
|
pub fn new() -> Self {
|
||||||
let mut lines = input.lines();
|
Self {
|
||||||
|
register_x: (1, 1),
|
||||||
let mut cycle = 1;
|
cycle: 1,
|
||||||
let mut is_busy = 0;
|
pixel_row: [false; Puter::LINE_WIDTH],
|
||||||
let mut v: i32 = 1;
|
rows: Vec::with_capacity(6),
|
||||||
let mut v_new: i32 = 1;
|
cycles_processing_left: 0,
|
||||||
let mut sig_str = vec![];
|
signal_strengths: Vec::with_capacity(6),
|
||||||
let mut pixels = [false; LINE_WIDTH];
|
|
||||||
let mut rows = vec![];
|
|
||||||
'outer: loop {
|
|
||||||
// Part 1
|
|
||||||
if cycle == 20 || (cycle > 20 && (cycle - 20) % LINE_WIDTH == 0) {
|
|
||||||
sig_str.push(cycle as i32 * v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_busy == 0 {
|
|
||||||
match lines.next() {
|
|
||||||
Some(s) => {
|
|
||||||
let cmd = Command::from_str(s);
|
|
||||||
match cmd {
|
|
||||||
Command::Noop => {}
|
|
||||||
Command::AddX(x) => {
|
|
||||||
v_new += x;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
is_busy = cmd.num_cycles();
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
break 'outer;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
is_busy -= 1;
|
|
||||||
|
|
||||||
let pixel = (cycle - 1) % LINE_WIDTH;
|
|
||||||
let is_lit = pixel.abs_diff(v as usize) <= SPRITE_WIDTH_HALF;
|
|
||||||
pixels[pixel] = is_lit;
|
|
||||||
if pixel == LINE_WIDTH - 1 {
|
|
||||||
let row: String = pixels.map(|l| if l { '#' } else { ' ' }).iter().collect();
|
|
||||||
rows.push(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
if is_busy == 0 {
|
|
||||||
v = v_new;
|
|
||||||
}
|
|
||||||
cycle += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn execute(&mut self, cmd: Command) {
|
||||||
|
match cmd {
|
||||||
|
Command::Noop => {}
|
||||||
|
Command::AddX(v) => {
|
||||||
|
self.register_x.1 += v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
self.cycles_processing_left = cmd.num_cycles();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(&mut self, program: &str) {
|
||||||
|
let mut lines = program.lines();
|
||||||
|
loop {
|
||||||
|
if self.cycles_processing_left == 0 {
|
||||||
|
match lines.next() {
|
||||||
|
Some(s) => self.execute(Command::from_str(s)),
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
self.cycles_processing_left -= 1;
|
||||||
|
|
||||||
|
let pixel = (self.cycle - 1) % Puter::LINE_WIDTH;
|
||||||
|
let is_lit = pixel.abs_diff(self.register_x.0 as usize) <= Puter::SPRITE_WIDTH_HALF;
|
||||||
|
self.pixel_row[pixel] = is_lit;
|
||||||
|
if pixel == Puter::LINE_WIDTH - 1 {
|
||||||
|
self.rows.push(
|
||||||
|
self.pixel_row
|
||||||
|
.map(|l| if l { '#' } else { ' ' })
|
||||||
|
.iter()
|
||||||
|
.collect(),
|
||||||
|
);
|
||||||
|
} else if pixel == (Puter::LINE_WIDTH / 2) - 1 {
|
||||||
|
self.signal_strengths
|
||||||
|
.push(self.cycle as i32 * self.register_x.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.cycles_processing_left == 0 {
|
||||||
|
self.register_x.0 = self.register_x.1;
|
||||||
|
}
|
||||||
|
self.cycle += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn signal_strengths(&self) -> Vec<i32> {
|
||||||
|
self.signal_strengths.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn output(&self) -> Vec<String> {
|
||||||
|
self.rows.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run() {
|
||||||
|
let input = read("10");
|
||||||
|
let mut device = Puter::new();
|
||||||
|
device.run(&input);
|
||||||
|
|
||||||
#[cfg(feature = "part1")]
|
#[cfg(feature = "part1")]
|
||||||
{
|
{
|
||||||
println!("Day 10, Part 01: {}", sig_str.iter().sum::<i32>());
|
println!(
|
||||||
|
"Day 10, Part 01: {}",
|
||||||
|
device.signal_strengths().iter().sum::<i32>()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "part2")]
|
#[cfg(feature = "part2")]
|
||||||
{
|
{
|
||||||
println!("Day 10, Part 02: \n{}", rows.join("\n"));
|
println!("Day 10, Part 02: \n{}", device.output().join("\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user