Update solution for 2022 day 10
Overengineer the solution just for fun
This commit is contained in:
parent
02f92114d3
commit
c173b62d37
@ -1,6 +1,6 @@
|
|||||||
use std::{env, io};
|
use std::{env, io};
|
||||||
|
|
||||||
use aoc_2022_10::{parse_input, Instruction};
|
use aoc_2022_10::Device;
|
||||||
|
|
||||||
fn main() -> io::Result<()> {
|
fn main() -> io::Result<()> {
|
||||||
let infile_path = env::args().nth(1).expect("input file");
|
let infile_path = env::args().nth(1).expect("input file");
|
||||||
@ -13,33 +13,26 @@ fn main() -> io::Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn solve(path: &str) -> io::Result<i64> {
|
fn solve(path: &str) -> io::Result<i64> {
|
||||||
let instructions = parse_input(path)?;
|
let mut device = Device::initialize(path)?;
|
||||||
|
|
||||||
let mut cycles_total: i64 = 0;
|
|
||||||
let mut reg_x: i64 = 1;
|
|
||||||
let mut sig_strength_total: i64 = 0;
|
let mut sig_strength_total: i64 = 0;
|
||||||
|
|
||||||
for instruction in instructions {
|
device.for_each_cycle(|cycles_total, reg_x| {
|
||||||
let (cycles, add_x) = match instruction {
|
compute_cycle(reg_x, cycles_total, &mut sig_strength_total);
|
||||||
Instruction::Noop => (1, 0),
|
});
|
||||||
Instruction::Addx(val) => (2, val),
|
|
||||||
};
|
|
||||||
|
|
||||||
for _ in 0..cycles {
|
|
||||||
cycles_total += 1;
|
|
||||||
|
|
||||||
if cycles_total == 20 || (cycles_total - 20) % 40 == 0 {
|
|
||||||
let sig_strength = cycles_total * reg_x;
|
|
||||||
sig_strength_total += sig_strength;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reg_x += add_x;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(sig_strength_total)
|
Ok(sig_strength_total)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compute_cycle(reg_x: i64, cycles_total: &mut i64, sig_strength_total: &mut i64) {
|
||||||
|
*cycles_total += 1;
|
||||||
|
|
||||||
|
if *cycles_total == 20 || (*cycles_total - 20) % 40 == 0 {
|
||||||
|
let sig_strength = *cycles_total * reg_x;
|
||||||
|
*sig_strength_total += sig_strength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::{env, io};
|
use std::{env, io};
|
||||||
|
|
||||||
use aoc_2022_10::{parse_input, Instruction};
|
use aoc_2022_10::Device;
|
||||||
|
|
||||||
fn main() -> io::Result<()> {
|
fn main() -> io::Result<()> {
|
||||||
let infile_path = env::args().nth(1).expect("input file");
|
let infile_path = env::args().nth(1).expect("input file");
|
||||||
@ -12,42 +12,22 @@ fn main() -> io::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CrtRow = [char; 40];
|
||||||
|
type Crt = Vec<CrtRow>;
|
||||||
|
|
||||||
const PIXEL_LIT: char = '#';
|
const PIXEL_LIT: char = '#';
|
||||||
const PIXEL_UNLIT: char = '.';
|
const PIXEL_UNLIT: char = '.';
|
||||||
const DRAW_CYCLE: i64 = 40;
|
const DRAW_CYCLE: i64 = 40;
|
||||||
|
|
||||||
fn solve(path: &str) -> io::Result<String> {
|
fn solve(path: &str) -> io::Result<String> {
|
||||||
let instructions = parse_input(path)?;
|
let mut device = Device::initialize(path)?;
|
||||||
|
|
||||||
let mut crt = Vec::<[char; 40]>::new();
|
let mut crt = Crt::new();
|
||||||
let mut crt_row = [PIXEL_UNLIT; 40];
|
let mut crt_row = [PIXEL_UNLIT; 40];
|
||||||
|
|
||||||
let mut cycles_total: i64 = 0;
|
device.for_each_cycle(|cycles_total, reg_x| {
|
||||||
let mut reg_x: i64 = 1;
|
compute_cycle(reg_x, cycles_total, &mut crt, &mut crt_row);
|
||||||
|
});
|
||||||
for instruction in instructions {
|
|
||||||
let (cycles, add_x) = match instruction {
|
|
||||||
Instruction::Noop => (1, 0),
|
|
||||||
Instruction::Addx(val) => (2, val),
|
|
||||||
};
|
|
||||||
|
|
||||||
for _ in 0..cycles {
|
|
||||||
let cur_row_pos = cycles_total % DRAW_CYCLE;
|
|
||||||
|
|
||||||
if ((reg_x - 1)..=(reg_x + 1)).contains(&cur_row_pos) {
|
|
||||||
crt_row[cur_row_pos as usize] = PIXEL_LIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
cycles_total += 1;
|
|
||||||
|
|
||||||
if cycles_total % DRAW_CYCLE == 0 {
|
|
||||||
crt.push(crt_row);
|
|
||||||
crt_row = [PIXEL_UNLIT; 40];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reg_x += add_x;
|
|
||||||
}
|
|
||||||
|
|
||||||
let lines = crt
|
let lines = crt
|
||||||
.iter()
|
.iter()
|
||||||
@ -58,6 +38,22 @@ fn solve(path: &str) -> io::Result<String> {
|
|||||||
Ok(lines)
|
Ok(lines)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compute_cycle(reg_x: i64, cycles_total: &mut i64, crt: &mut Crt, crt_row: &mut CrtRow) {
|
||||||
|
let cur_row_pos = *cycles_total % DRAW_CYCLE;
|
||||||
|
let sprite_area = (reg_x - 1)..=(reg_x + 1);
|
||||||
|
|
||||||
|
if sprite_area.contains(&cur_row_pos) {
|
||||||
|
crt_row[cur_row_pos as usize] = PIXEL_LIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
*cycles_total += 1;
|
||||||
|
|
||||||
|
if *cycles_total % DRAW_CYCLE == 0 {
|
||||||
|
crt.push(*crt_row);
|
||||||
|
*crt_row = [PIXEL_UNLIT; 40];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -4,12 +4,60 @@ use std::{
|
|||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub enum Instruction {
|
pub struct Device {
|
||||||
|
instructions: Vec<Instruction>,
|
||||||
|
cycles_total: i64,
|
||||||
|
reg_x: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Device {
|
||||||
|
pub fn initialize<P>(path: P) -> io::Result<Self>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let instructions = parse_input(path)?;
|
||||||
|
Ok(Self {
|
||||||
|
instructions,
|
||||||
|
cycles_total: 0,
|
||||||
|
reg_x: 1,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn for_each_cycle<F>(&mut self, mut cycle_fn: F)
|
||||||
|
where
|
||||||
|
F: FnMut(&mut i64, i64),
|
||||||
|
{
|
||||||
|
for instruction in &self.instructions {
|
||||||
|
for _ in 0..instruction.cycles() {
|
||||||
|
cycle_fn(&mut self.cycles_total, self.reg_x);
|
||||||
|
}
|
||||||
|
self.reg_x += instruction.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Instruction {
|
||||||
Noop,
|
Noop,
|
||||||
Addx(i64),
|
Addx(i64),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_input<P>(path: P) -> io::Result<Vec<Instruction>>
|
impl Instruction {
|
||||||
|
pub fn cycles(&self) -> i64 {
|
||||||
|
match self {
|
||||||
|
Self::Noop => 1,
|
||||||
|
Self::Addx(_) => 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn value(&self) -> i64 {
|
||||||
|
match self {
|
||||||
|
Self::Noop => 0,
|
||||||
|
Self::Addx(val) => *val,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_input<P>(path: P) -> io::Result<Vec<Instruction>>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user