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,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(),
}