2022 day10/rust: use generators
This commit is contained in:
parent
135a5017f7
commit
0618083106
1 changed files with 59 additions and 17 deletions
|
@ -1,3 +1,6 @@
|
|||
#![feature(generators)]
|
||||
#![feature(generator_clone)]
|
||||
#![feature(iter_from_generator)]
|
||||
#![warn(clippy::pedantic)]
|
||||
|
||||
use std::{
|
||||
|
@ -6,9 +9,48 @@ use std::{
|
|||
str::FromStr,
|
||||
};
|
||||
|
||||
type Word = i64;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
struct MachineState {
|
||||
x: Word,
|
||||
}
|
||||
|
||||
impl MachineState {
|
||||
const fn new() -> Self {
|
||||
Self { x: 1 }
|
||||
}
|
||||
|
||||
fn execute(&mut self, op: MicroOp) {
|
||||
match op {
|
||||
MicroOp::Noop => {}
|
||||
MicroOp::Addx(i) => self.x += i,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum MicroOp {
|
||||
Noop,
|
||||
Addx(Word),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum Instruction {
|
||||
Noop,
|
||||
Addx(i32),
|
||||
Addx(Word),
|
||||
}
|
||||
|
||||
impl Instruction {
|
||||
pub fn expand(self) -> impl Iterator<Item = MicroOp> {
|
||||
iter::from_generator(move || match self {
|
||||
Self::Noop => yield MicroOp::Noop,
|
||||
Self::Addx(x) => {
|
||||
yield MicroOp::Noop;
|
||||
yield MicroOp::Addx(x);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Instruction {
|
||||
|
@ -28,35 +70,35 @@ impl FromStr for Instruction {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
const START: MachineState = MachineState::new();
|
||||
|
||||
let mut data = String::new();
|
||||
stdin().read_to_string(&mut data).unwrap();
|
||||
|
||||
let values = data
|
||||
let states: Vec<_> = data
|
||||
.lines()
|
||||
.map(|l| l.parse().unwrap())
|
||||
.flat_map(|i: Instruction| match i {
|
||||
Instruction::Noop => vec![0],
|
||||
Instruction::Addx(i) => vec![0, i],
|
||||
.flat_map(Instruction::expand)
|
||||
.scan(START, |state, op| {
|
||||
let prev = state.clone();
|
||||
state.execute(op);
|
||||
Some(prev)
|
||||
})
|
||||
.scan(1, |acc, i| {
|
||||
*acc += i;
|
||||
Some(*acc)
|
||||
});
|
||||
let values = iter::once(1)
|
||||
.chain(values)
|
||||
.enumerate()
|
||||
.map(|(i, x)| (i32::try_from(i).unwrap() + 1, x));
|
||||
.map(|(i, state)| (Word::try_from(i).unwrap() + 1, state))
|
||||
.collect();
|
||||
|
||||
let sum: i32 = values
|
||||
.clone()
|
||||
let sum: Word = states
|
||||
.iter()
|
||||
.skip(20 - 1)
|
||||
.step_by(40)
|
||||
.map(|(i, x)| i * x)
|
||||
.map(|(i, state)| i * state.x)
|
||||
.sum();
|
||||
println!("{:?}", sum);
|
||||
|
||||
let crt: Vec<_> = values
|
||||
.map(|(i, x)| ((i - 1) % 40).abs_diff(x) < 2)
|
||||
let crt: Vec<_> = states
|
||||
.iter()
|
||||
.map(|(i, state)| ((i - 1) % 40).abs_diff(state.x) < 2)
|
||||
.map(|x| if x { '#' } else { '.' })
|
||||
.collect();
|
||||
|
||||
|
|
Loading…
Reference in a new issue