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;
|
||||
|
||||
#[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() {
|
||||
let input = read("10");
|
||||
let mut device = Puter::new();
|
||||
|
@ -11,6 +11,7 @@ mod day07;
|
||||
mod day08;
|
||||
mod day09;
|
||||
mod day10;
|
||||
mod puter;
|
||||
|
||||
fn main() {
|
||||
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