1
0
Fork 0

day(22): switch to proper vectors

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

View file

@ -5,6 +5,10 @@ use aoc_2022::*;
type Input = MonkeyMap; type Input = MonkeyMap;
type Output = isize; type Output = isize;
type Position = Vector2D<usize>;
type Direction = Vector2D<isize>;
type Boundary = Vector2D<usize>;
enum Instruction { enum Instruction {
Move(usize), Move(usize),
TurnLeft, TurnLeft,
@ -19,56 +23,90 @@ enum Orientation {
struct MonkeyMap { struct MonkeyMap {
map: Vec<Vec<char>>, map: Vec<Vec<char>>,
boundaries: HashMap<Orientation, (usize, usize)>, boundaries: HashMap<Orientation, Boundary>,
instructions: Vec<Instruction>, instructions: Vec<Instruction>,
} }
fn wrapping_step(position: usize, diff: isize, range: Boundary) -> usize {
let (lower, upper) = (range.x(), range.y());
let range_size = (upper - lower) as isize;
(lower as isize + (position as isize + diff - lower as isize + range_size) % range_size)
as usize
}
trait Wrap { trait Wrap {
fn next(&self, state: &State<'_>) -> (usize, usize); fn next(&self, state: &State<'_>) -> (Position, Direction);
} }
struct Wrap2D; 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 { impl Wrap for Wrap2D {
fn next(&self, state: &State<'_>) -> (usize, usize) { fn next(&self, state: &State<'_>) -> (Position, Direction) {
let h_bound = state.input.boundaries[&Orientation::Horizontal(state.y)]; let h_bound = state.input.boundaries[&Orientation::Horizontal(state.position.y())];
let v_bound = state.input.boundaries[&Orientation::Vertical(state.x)]; let v_bound = state.input.boundaries[&Orientation::Vertical(state.position.x())];
let (dx, dy) = state.direction;
( (
Self::step(state.x, dx, h_bound.0, h_bound.1), Position::new(
Self::step(state.y, dy, v_bound.0, v_bound.1), wrapping_step(state.position.x(), state.direction.x(), h_bound),
wrapping_step(state.position.y(), state.direction.y(), v_bound),
),
state.direction,
)
}
}
struct Face {
horizontal_bound: Boundary,
vertical_bound: Boundary,
}
struct Wrap3D {
faces: Vec<Face>,
}
impl Wrap3D {
fn face(&self, position: Position) -> &Face {
let (x, y) = (position.x(), position.y());
for f in &self.faces {}
todo!()
}
}
impl Wrap for Wrap3D {
fn next(&self, state: &State<'_>) -> (Position, Direction) {
let face = self.face(state.position);
(
Position::new(
wrapping_step(
state.position.x(),
state.direction.x(),
face.horizontal_bound,
),
wrapping_step(state.position.y(), state.direction.y(), face.vertical_bound),
),
state.direction,
) )
} }
} }
struct State<'a> { struct State<'a> {
input: &'a Input, input: &'a Input,
y: usize, position: Position,
x: usize, direction: Direction,
direction: (isize, isize),
} }
impl<'a> State<'a> { impl<'a> State<'a> {
fn new(input: &'a Input) -> State<'a> { fn new(input: &'a Input) -> State<'a> {
Self { Self {
input, input,
y: 0, position: Position::new(input.boundaries[&Orientation::Horizontal(0)].x(), 0),
x: input.boundaries[&Orientation::Horizontal(0)].0, direction: Direction::new(1, 0),
direction: (1, 0),
} }
} }
fn is_blocked(&self, wrapper: &impl Wrap) -> bool { fn is_blocked(&self, wrapper: &impl Wrap) -> bool {
let (x, y) = wrapper.next(self); let (next_position, _) = wrapper.next(self);
self.input.map[y][x] == '#' self.input.map[next_position] == '#'
} }
fn step(&mut self, wrapper: &impl Wrap, steps: usize) { fn step(&mut self, wrapper: &impl Wrap, steps: usize) {
@ -76,18 +114,18 @@ impl<'a> State<'a> {
if self.is_blocked(wrapper) { if self.is_blocked(wrapper) {
return; return;
} }
(self.x, self.y) = wrapper.next(self); (self.position, self.direction) = wrapper.next(self);
} }
} }
fn turn_left(&mut self) { fn turn_left(&mut self) {
let (x, y) = self.direction; let previous = self.direction;
self.direction = (y, -x); self.direction = Direction::new(previous.y(), -previous.x());
} }
fn turn_right(&mut self) { fn turn_right(&mut self) {
let (x, y) = self.direction; let previous = self.direction;
self.direction = (-y, x); self.direction = Direction::new(-previous.y(), previous.x());
} }
} }
@ -110,7 +148,9 @@ fn solve(wrapper: &impl Wrap, input: &Input) -> Output {
state state
}); });
(1000 * (final_state.y + 1) + 4 * (final_state.x + 1) + DIRECTIONS[&final_state.direction]) (1000 * (final_state.position.y() + 1)
+ 4 * (final_state.position.x() + 1)
+ DIRECTIONS[&(final_state.direction.x(), final_state.direction.y())])
.try_into() .try_into()
.unwrap() .unwrap()
} }
@ -133,7 +173,7 @@ impl Solution<Input, Output> for Day22 {
let mut last_non_empty = first_non_empty.skip_while(|&(_, &c)| c != ' '); let mut last_non_empty = first_non_empty.skip_while(|&(_, &c)| c != ' ');
let end = last_non_empty.next().unwrap_or((map[row].len(), &'_')).0; let end = last_non_empty.next().unwrap_or((map[row].len(), &'_')).0;
boundaries.insert(Orientation::Horizontal(row), (start, end)); boundaries.insert(Orientation::Horizontal(row), Boundary::new(start, end));
} }
for col in 0..map[0].len() { for col in 0..map[0].len() {
@ -145,7 +185,7 @@ impl Solution<Input, Output> for Day22 {
let mut last_non_empty = first_non_empty.skip_while(|&(_, &c)| c != ' '); let mut last_non_empty = first_non_empty.skip_while(|&(_, &c)| c != ' ');
let end = last_non_empty.next().unwrap_or((map.len(), &'_')).0; let end = last_non_empty.next().unwrap_or((map.len(), &'_')).0;
boundaries.insert(Orientation::Vertical(col), (start, end)); boundaries.insert(Orientation::Vertical(col), Boundary::new(start, end));
} }
let unparsed_instructions_str = instructions.trim_end(); let unparsed_instructions_str = instructions.trim_end();
@ -185,8 +225,9 @@ impl Solution<Input, Output> for Day22 {
solve(&Wrap2D, input) solve(&Wrap2D, input)
} }
fn part_2(_input: &Input) -> Output { fn part_2(input: &Input) -> Output {
todo!() let wrapper = Wrap2D;
solve(&wrapper, input)
} }
} }