Migrate day 12 to PositionND

This commit is contained in:
kageru 2021-07-08 19:27:56 +02:00
parent 98b8a9c81c
commit c726998c0c
Signed by: kageru
GPG Key ID: 8282A2BEA4ADA3D2
2 changed files with 39 additions and 16 deletions

View File

@ -18,23 +18,23 @@ fn parse_input(raw: &str) -> Parsed {
fn part1(parsed: &Parsed) -> i64 { fn part1(parsed: &Parsed) -> i64 {
let end_pos = parsed let end_pos = parsed
.iter() .iter()
.fold((Direction::Right, Position2D { x: 0, y: 0 }), |(dir, pos), (cmd, dist)| match cmd { .fold((Direction::Right, PositionND::from([0, 0])), |(dir, pos), (cmd, dist)| match cmd {
'N' => (dir, pos + Position2D::from((0, *dist))), 'N' => (dir, pos + PositionND::from([0, *dist])),
'S' => (dir, pos - Position2D::from((0, *dist))), 'S' => (dir, pos - PositionND::from([0, *dist])),
'E' => (dir, pos + Position2D::from((*dist, 0))), 'E' => (dir, pos + PositionND::from([*dist, 0])),
'W' => (dir, pos - Position2D::from((*dist, 0))), 'W' => (dir, pos - PositionND::from([*dist, 0])),
'R' => (dir + (dist / 90) as i8, pos), 'R' => (dir + (dist / 90) as i8, pos),
'L' => (dir + -(dist / 90) as i8, pos), 'L' => (dir + -(dist / 90) as i8, pos),
'F' => (dir, pos + Position2D::from(dir) * *dist), 'F' => (dir, pos + PositionND::from(dir) * *dist),
_ => unreachable!(), _ => unreachable!(),
}) })
.1; .1;
end_pos.x.abs() + end_pos.y.abs() end_pos.points[0].abs() + end_pos.points[1].abs()
} }
fn rotate_waypoint(mut wp: Position2D, deg: i64) -> Position2D { fn rotate_waypoint(mut wp: PositionND<2>, deg: i64) -> PositionND<2> {
for _ in 0..((deg / 90 + 4) & 3) { for _ in 0..((deg / 90 + 4) & 3) {
wp = Position2D { x: wp.y, y: -wp.x }; wp = PositionND::from([wp.points[1], -wp.points[0]]);
} }
wp wp
} }
@ -43,12 +43,12 @@ fn part2(parsed: &Parsed) -> i64 {
let end_pos = parsed let end_pos = parsed
.iter() .iter()
.fold( .fold(
(Position2D { x: 10, y: 1 }, Position2D { x: 0, y: 0 }), (PositionND::from([10, 1]), PositionND::from([0, 0])),
|(wp, pos), (cmd, dist)| match cmd { |(wp, pos), (cmd, dist)| match cmd {
'N' => (wp + Position2D::from((0, *dist)), pos), 'N' => (wp + PositionND::from([0, *dist]), pos),
'S' => (wp - Position2D::from((0, *dist)), pos), 'S' => (wp - PositionND::from([0, *dist]), pos),
'E' => (wp + Position2D::from((*dist, 0)), pos), 'E' => (wp + PositionND::from([*dist, 0]), pos),
'W' => (wp - Position2D::from((*dist, 0)), pos), 'W' => (wp - PositionND::from([*dist, 0]), pos),
'R' => (rotate_waypoint(wp, *dist), pos), 'R' => (rotate_waypoint(wp, *dist), pos),
'L' => (rotate_waypoint(wp, -dist), pos), 'L' => (rotate_waypoint(wp, -dist), pos),
'F' => (wp, pos + wp * *dist), 'F' => (wp, pos + wp * *dist),
@ -56,7 +56,7 @@ fn part2(parsed: &Parsed) -> i64 {
}, },
) )
.1; .1;
end_pos.x.abs() + end_pos.y.abs() end_pos.points[0].abs() + end_pos.points[1].abs()
} }
fn main() { fn main() {

View File

@ -3,7 +3,7 @@ use super::direction::*;
use impl_ops::*; use impl_ops::*;
use itertools::iproduct; use itertools::iproduct;
use std::{ use std::{
convert::TryInto, hash::Hash, ops::{self, Add, AddAssign, Mul} convert::TryInto, hash::Hash, ops::{self, Add, AddAssign, Mul, Sub}
}; };
pub trait Position pub trait Position
@ -151,6 +151,29 @@ impl<const D: usize> Add<PositionND<D>> for PositionND<D> {
} }
} }
impl<const D: usize> Sub<PositionND<D>> for PositionND<D> {
type Output = PositionND<D>;
fn sub(self, rhs: PositionND<D>) -> Self::Output {
let mut points = [0; D];
for i in 0..D {
points[i] = self.points[i] - rhs.points[i];
}
PositionND { points }
}
}
impl From<Direction> for PositionND<2> {
fn from(d: Direction) -> Self {
match d {
Direction::Up => PositionND::from([0, 1]),
Direction::Right => PositionND::from([1, 0]),
Direction::Left => PositionND::from([-1, 0]),
Direction::Down => PositionND::from([0, -1]),
}
}
}
mod p2d { mod p2d {
use super::*; use super::*;