day(22): factor out wrapping to a trait
Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
parent
775ee061d5
commit
fcdff3c129
1 changed files with 32 additions and 22 deletions
|
@ -23,11 +23,31 @@ struct MonkeyMap {
|
|||
instructions: Vec<Instruction>,
|
||||
}
|
||||
|
||||
fn step_with_wrap(position: usize, diff: isize, lower: usize, upper: usize) -> usize {
|
||||
trait Wrap {
|
||||
fn next(&self, state: &State<'_>) -> (usize, usize);
|
||||
}
|
||||
|
||||
struct Wrap2D;
|
||||
impl Wrap2D {
|
||||
fn step(position: usize, diff: isize, lower: usize, upper: usize) -> usize {
|
||||
let range_size = (upper - lower) as isize;
|
||||
(lower as isize + (position as isize + diff - lower as isize + range_size) % range_size)
|
||||
as usize
|
||||
}
|
||||
}
|
||||
impl Wrap for Wrap2D {
|
||||
fn next(&self, state: &State<'_>) -> (usize, usize) {
|
||||
let h_bound = state.input.boundaries[&Orientation::Horizontal(state.y)];
|
||||
let v_bound = state.input.boundaries[&Orientation::Vertical(state.x)];
|
||||
|
||||
let (dx, dy) = state.direction;
|
||||
|
||||
(
|
||||
Self::step(state.x, dx, h_bound.0, h_bound.1),
|
||||
Self::step(state.y, dy, v_bound.0, v_bound.1),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct State<'a> {
|
||||
input: &'a Input,
|
||||
|
@ -46,29 +66,17 @@ impl<'a> State<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn next(&self) -> (usize, usize) {
|
||||
let h_bound = self.input.boundaries[&Orientation::Horizontal(self.y)];
|
||||
let v_bound = self.input.boundaries[&Orientation::Vertical(self.x)];
|
||||
|
||||
let (dx, dy) = self.direction;
|
||||
|
||||
(
|
||||
step_with_wrap(self.x, dx, h_bound.0, h_bound.1),
|
||||
step_with_wrap(self.y, dy, v_bound.0, v_bound.1),
|
||||
)
|
||||
}
|
||||
|
||||
fn is_blocked(&self) -> bool {
|
||||
let (x, y) = self.next();
|
||||
fn is_blocked(&self, wrapper: &impl Wrap) -> bool {
|
||||
let (x, y) = wrapper.next(self);
|
||||
self.input.map[y][x] == '#'
|
||||
}
|
||||
|
||||
fn step(&mut self, steps: usize) {
|
||||
fn step(&mut self, wrapper: &impl Wrap, steps: usize) {
|
||||
for _ in 0..steps {
|
||||
if self.is_blocked() {
|
||||
if self.is_blocked(wrapper) {
|
||||
return;
|
||||
}
|
||||
(self.x, self.y) = self.next();
|
||||
(self.x, self.y) = wrapper.next(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,12 +163,14 @@ impl Solution<Input, Output> for Day22 {
|
|||
}
|
||||
|
||||
fn part_1(input: &Input) -> Output {
|
||||
let wrapper = Wrap2D;
|
||||
|
||||
let final_state = input
|
||||
.instructions
|
||||
.iter()
|
||||
.fold(State::new(input), |mut state, y| {
|
||||
match &y {
|
||||
Instruction::Move(steps) => state.step(*steps),
|
||||
Instruction::Move(steps) => state.step(&wrapper, *steps),
|
||||
Instruction::TurnLeft => state.turn_left(),
|
||||
Instruction::TurnRight => state.turn_right(),
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue