1
0
Fork 0

day(22): factor out wrapping to a trait

Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
Matej Focko 2023-07-05 20:16:49 +02:00
parent 775ee061d5
commit fcdff3c129
Signed by: mfocko
GPG key ID: 7C47D46246790496

View file

@ -23,10 +23,30 @@ struct MonkeyMap {
instructions: Vec<Instruction>, 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; let range_size = (upper - lower) as isize;
(lower as isize + (position as isize + diff - lower as isize + range_size) % range_size) (lower as isize + (position as isize + diff - lower as isize + range_size) % range_size)
as usize 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> { struct State<'a> {
@ -46,29 +66,17 @@ impl<'a> State<'a> {
} }
} }
fn next(&self) -> (usize, usize) { fn is_blocked(&self, wrapper: &impl Wrap) -> bool {
let h_bound = self.input.boundaries[&Orientation::Horizontal(self.y)]; let (x, y) = wrapper.next(self);
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();
self.input.map[y][x] == '#' self.input.map[y][x] == '#'
} }
fn step(&mut self, steps: usize) { fn step(&mut self, wrapper: &impl Wrap, steps: usize) {
for _ in 0..steps { for _ in 0..steps {
if self.is_blocked() { if self.is_blocked(wrapper) {
return; 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 { fn part_1(input: &Input) -> Output {
let wrapper = Wrap2D;
let final_state = input let final_state = input
.instructions .instructions
.iter() .iter()
.fold(State::new(input), |mut state, y| { .fold(State::new(input), |mut state, y| {
match &y { match &y {
Instruction::Move(steps) => state.step(*steps), Instruction::Move(steps) => state.step(&wrapper, *steps),
Instruction::TurnLeft => state.turn_left(), Instruction::TurnLeft => state.turn_left(),
Instruction::TurnRight => state.turn_right(), Instruction::TurnRight => state.turn_right(),
} }