Move Puter to its own module
This commit is contained in:
parent
dfb8421dec
commit
c09126a27e
107
src/day10/mod.rs
107
src/day10/mod.rs
@ -1,111 +1,6 @@
|
|||||||
|
use crate::puter::Puter;
|
||||||
use crate::read;
|
use crate::read;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
|
||||||
enum Command {
|
|
||||||
AddX(i32),
|
|
||||||
Noop,
|
|
||||||
}
|
|
||||||
impl Command {
|
|
||||||
fn from_str(s: &str) -> Self {
|
|
||||||
match s {
|
|
||||||
"noop" => Command::Noop,
|
|
||||||
s => {
|
|
||||||
let (c, i) = s.split_once(' ').unwrap();
|
|
||||||
match (c, i.parse::<i32>()) {
|
|
||||||
("addx", Ok(i)) => Self::AddX(i),
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn num_cycles(&self) -> usize {
|
|
||||||
match self {
|
|
||||||
Self::Noop => 1,
|
|
||||||
Self::AddX(_) => 2,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 SPRITE_WIDTH: usize = 3;
|
|
||||||
const SPRITE_WIDTH_HALF: usize = Puter::SPRITE_WIDTH / 2;
|
|
||||||
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
register_x: (1, 1),
|
|
||||||
cycle: 1,
|
|
||||||
pixel_row: [false; Puter::LINE_WIDTH],
|
|
||||||
rows: Vec::with_capacity(6),
|
|
||||||
cycles_processing_left: 0,
|
|
||||||
signal_strengths: Vec::with_capacity(6),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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() {
|
pub fn run() {
|
||||||
let input = read("10");
|
let input = read("10");
|
||||||
let mut device = Puter::new();
|
let mut device = Puter::new();
|
||||||
|
@ -11,6 +11,7 @@ mod day07;
|
|||||||
mod day08;
|
mod day08;
|
||||||
mod day09;
|
mod day09;
|
||||||
mod day10;
|
mod day10;
|
||||||
|
mod puter;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let today = Local::now().day();
|
let today = Local::now().day();
|
||||||
|
105
src/puter/mod.rs
Normal file
105
src/puter/mod.rs
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
||||||
|
pub(crate) enum Command {
|
||||||
|
AddX(i32),
|
||||||
|
Noop,
|
||||||
|
}
|
||||||
|
impl Command {
|
||||||
|
fn from_str(s: &str) -> Self {
|
||||||
|
match s {
|
||||||
|
"noop" => Command::Noop,
|
||||||
|
s => {
|
||||||
|
let (c, i) = s.split_once(' ').unwrap();
|
||||||
|
match (c, i.parse::<i32>()) {
|
||||||
|
("addx", Ok(i)) => Self::AddX(i),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn num_cycles(&self) -> usize {
|
||||||
|
match self {
|
||||||
|
Self::Noop => 1,
|
||||||
|
Self::AddX(_) => 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) 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 SPRITE_WIDTH: usize = 3;
|
||||||
|
const SPRITE_WIDTH_HALF: usize = Puter::SPRITE_WIDTH / 2;
|
||||||
|
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
register_x: (1, 1),
|
||||||
|
cycle: 1,
|
||||||
|
pixel_row: [false; Puter::LINE_WIDTH],
|
||||||
|
rows: Vec::with_capacity(6),
|
||||||
|
cycles_processing_left: 0,
|
||||||
|
signal_strengths: Vec::with_capacity(6),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user