day 10
This commit is contained in:
parent
b6f95ae9aa
commit
631d12ac32
103
src/days/day10.rs
Normal file
103
src/days/day10.rs
Normal file
|
@ -0,0 +1,103 @@
|
|||
use aoc_runner_derive::{aoc, aoc_generator};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum Instruction {
|
||||
AddX(i32),
|
||||
NoOp,
|
||||
}
|
||||
|
||||
#[aoc_generator(day10)]
|
||||
fn generator(input: &str) -> Vec<Instruction> {
|
||||
input
|
||||
.lines()
|
||||
.map(|l| {
|
||||
if l == "noop" {
|
||||
Instruction::NoOp
|
||||
} else if let Some(l) = l.strip_prefix("addx ") {
|
||||
Instruction::AddX(l.parse().unwrap())
|
||||
} else {
|
||||
panic!()
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
struct CpuState {
|
||||
cycle: i32,
|
||||
x: i32,
|
||||
}
|
||||
|
||||
fn run_simulation(input: &[Instruction], mut during_cycle_handler: impl FnMut(CpuState)) {
|
||||
let mut cycle = 1;
|
||||
let mut x = 1;
|
||||
let mut iter = input.iter().copied();
|
||||
let mut current_instruction = iter.next().unwrap();
|
||||
let mut current_instruction_cycle = 0;
|
||||
|
||||
// god i hate fenceposts
|
||||
loop {
|
||||
// START OF CYCLE
|
||||
|
||||
let need_new_instruction = match (current_instruction, current_instruction_cycle) {
|
||||
(_, 0) => false,
|
||||
(Instruction::NoOp, 1) => true,
|
||||
(Instruction::AddX(_), 1) => false,
|
||||
(Instruction::AddX(v), 2) => {
|
||||
x += v;
|
||||
true
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
if need_new_instruction {
|
||||
let Some(tmp) = iter.next() else {
|
||||
break
|
||||
};
|
||||
current_instruction = tmp;
|
||||
current_instruction_cycle = 0;
|
||||
}
|
||||
|
||||
// DURING CYCLE
|
||||
|
||||
during_cycle_handler(CpuState { cycle, x });
|
||||
|
||||
// END OF CYCLE
|
||||
|
||||
current_instruction_cycle += 1;
|
||||
cycle += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[aoc(day10, part1)]
|
||||
fn part1(input: &[Instruction]) -> i32 {
|
||||
let mut res = 0;
|
||||
|
||||
run_simulation(input, |CpuState { cycle, x }| {
|
||||
if (cycle + 20) % 40 == 0 {
|
||||
res += cycle * x;
|
||||
}
|
||||
});
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
#[aoc(day10, part2)]
|
||||
fn part2(input: &[Instruction]) -> String {
|
||||
let mut res = "\n".to_owned(); // newline so that `cargo aoc` formats this nicely
|
||||
|
||||
run_simulation(input, |CpuState { cycle, x }| {
|
||||
let crt_x_pos = (cycle - 1) % 40;
|
||||
|
||||
if (crt_x_pos - x).abs() <= 1 {
|
||||
res.push('#');
|
||||
} else {
|
||||
res.push(' '); // the puzzle says `.` but ` ` is more readable
|
||||
}
|
||||
|
||||
if cycle % 40 == 0 {
|
||||
res.push('\n');
|
||||
}
|
||||
});
|
||||
|
||||
res
|
||||
}
|
|
@ -10,6 +10,8 @@ mod days {
|
|||
mod day7;
|
||||
mod day8;
|
||||
mod day9;
|
||||
// curse you, rustfmt
|
||||
mod day10;
|
||||
}
|
||||
|
||||
aoc_lib! { year = 2022 }
|
||||
|
|
Loading…
Reference in a new issue