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)]
|
#![warn(clippy::pedantic)]
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -6,9 +9,48 @@ use std::{
|
||||||
str::FromStr,
|
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 {
|
enum Instruction {
|
||||||
Noop,
|
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 {
|
impl FromStr for Instruction {
|
||||||
|
@ -28,35 +70,35 @@ impl FromStr for Instruction {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
const START: MachineState = MachineState::new();
|
||||||
|
|
||||||
let mut data = String::new();
|
let mut data = String::new();
|
||||||
stdin().read_to_string(&mut data).unwrap();
|
stdin().read_to_string(&mut data).unwrap();
|
||||||
|
|
||||||
let values = data
|
let states: Vec<_> = data
|
||||||
.lines()
|
.lines()
|
||||||
.map(|l| l.parse().unwrap())
|
.map(|l| l.parse().unwrap())
|
||||||
.flat_map(|i: Instruction| match i {
|
.flat_map(Instruction::expand)
|
||||||
Instruction::Noop => vec![0],
|
.scan(START, |state, op| {
|
||||||
Instruction::Addx(i) => vec![0, i],
|
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()
|
.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
|
let sum: Word = states
|
||||||
.clone()
|
.iter()
|
||||||
.skip(20 - 1)
|
.skip(20 - 1)
|
||||||
.step_by(40)
|
.step_by(40)
|
||||||
.map(|(i, x)| i * x)
|
.map(|(i, state)| i * state.x)
|
||||||
.sum();
|
.sum();
|
||||||
println!("{:?}", sum);
|
println!("{:?}", sum);
|
||||||
|
|
||||||
let crt: Vec<_> = values
|
let crt: Vec<_> = states
|
||||||
.map(|(i, x)| ((i - 1) % 40).abs_diff(x) < 2)
|
.iter()
|
||||||
|
.map(|(i, state)| ((i - 1) % 40).abs_diff(state.x) < 2)
|
||||||
.map(|x| if x { '#' } else { '.' })
|
.map(|x| if x { '#' } else { '.' })
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue