Skip to content

Commit

Permalink
[2023] Use common Direction enum
Browse files Browse the repository at this point in the history
  • Loading branch information
connorslade committed Dec 17, 2023
1 parent 16ae4d9 commit 32dc239
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 109 deletions.
67 changes: 67 additions & 0 deletions aoc_2023/src/aoc_lib/direction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use nd_vec::{vector, Vec2};
use num_traits::Num;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Direction {
Up,
Down,
Left,
Right,
}

impl Direction {
pub const ALL: [Direction; 4] = [
Direction::Up,
Direction::Down,
Direction::Left,
Direction::Right,
];

#[rustfmt::skip]
pub fn try_advance<T: Num + Copy + PartialOrd>(&self, pos: Vec2<T>) -> Option<Vec2<T>> {
Some(match self {
Self::Up if pos.y() > T::zero() => vector!(pos.x(), pos.y() - T::one()),
Self::Down => vector!(pos.x(), pos.y() + T::one()),
Self::Left if pos.x() > T::zero() => vector!(pos.x() - T::one(), pos.y()),
Self::Right => vector!(pos.x() + T::one(), pos.y()),
_ => return None,
})
}

#[rustfmt::skip]
pub fn advance<T: Num + Copy>(&self, pos: Vec2<T>) -> Vec2<T> {
match self {
Self::Up => vector!(pos.x(), pos.y() - T::one()),
Self::Down => vector!(pos.x(), pos.y() + T::one()),
Self::Left => vector!(pos.x() - T::one(), pos.y()),
Self::Right => vector!(pos.x() + T::one(), pos.y()),
}
}

pub fn opposite(&self) -> Self {
match self {
Self::Up => Self::Down,
Self::Down => Self::Up,
Self::Left => Self::Right,
Self::Right => Self::Left,
}
}

pub fn turn_left(&self) -> Self {
match self {
Self::Up => Self::Left,
Self::Down => Self::Right,
Self::Left => Self::Down,
Self::Right => Self::Up,
}
}

pub fn turn_right(&self) -> Self {
match self {
Self::Up => Self::Right,
Self::Down => Self::Left,
Self::Left => Self::Up,
Self::Right => Self::Down,
}
}
}
1 change: 1 addition & 0 deletions aoc_2023/src/aoc_lib/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[macro_use]
pub mod regex;
pub mod direction;
pub mod math;
40 changes: 3 additions & 37 deletions aoc_2023/src/day_10.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use nd_vec::{vector, Vec2};

use common::{Answer, Solution};

use crate::aoc_lib::direction::Direction;

type Pos = Vec2<usize>;

const START_PIECES: [(char, [Direction; 2]); 4] = [
Expand Down Expand Up @@ -77,14 +79,6 @@ enum Riding {
Down,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
enum Direction {
Up,
Down,
Left,
Right,
}

struct Maze {
start: Pos,
segments: Vec<Vec<char>>,
Expand Down Expand Up @@ -122,7 +116,7 @@ impl Maze {
start_approaches[0] = dir;
loop {
walls.insert(pos);
pos = match dir.step(pos) {
pos = match dir.try_advance(pos) {
Some(p) => p,
None => break,
};
Expand Down Expand Up @@ -167,34 +161,6 @@ enum TurnResult {
Fail,
}

impl Direction {
const ALL: [Direction; 4] = [
Direction::Up,
Direction::Down,
Direction::Left,
Direction::Right,
];

fn step(&self, pos: Pos) -> Option<Pos> {
Some(match self {
Direction::Up if pos.y() > 0 => vector!(pos.x(), pos.y() - 1),
Direction::Down => vector!(pos.x(), pos.y() + 1),
Direction::Left if pos.x() > 0 => vector!(pos.x() - 1, pos.y()),
Direction::Right => vector!(pos.x() + 1, pos.y()),
_ => return None,
})
}

fn opposite(&self) -> Self {
match self {
Direction::Up => Direction::Down,
Direction::Down => Direction::Up,
Direction::Left => Direction::Right,
Direction::Right => Direction::Left,
}
}
}

fn turn(facing: Direction, tile: char) -> TurnResult {
TurnResult::Turn(match (tile, facing) {
('|' | '-', _) => facing,
Expand Down
24 changes: 3 additions & 21 deletions aoc_2023/src/day_16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use common::{Answer, Solution};
use itertools::Itertools;
use nd_vec::{vector, Vec2};

use crate::aoc_lib::direction::Direction;

type Pos = Vec2<isize>;

pub struct Day16;
Expand Down Expand Up @@ -40,14 +42,6 @@ struct Cavern {
tiles: Vec<Vec<Tile>>,
}

#[derive(Debug, Clone, Copy)]
enum Direction {
Up,
Down,
Left,
Right,
}

#[derive(Debug, Clone, Copy, PartialEq)]
enum Tile {
Empty, // .
Expand All @@ -69,7 +63,7 @@ fn parse(input: &str) -> Cavern {
impl Cavern {
fn lazer(&self, start: Pos, direction: Direction) -> usize {
fn _lazer(cavern: &Cavern, visited: &mut HashSet<Pos>, mut pos: Pos, mut dir: Direction) {
while let Some(i) = dir.advance(pos) {
while let Some(i) = dir.try_advance(pos) {
pos = i;

if pos.x() >= cavern.tiles[0].len() as isize
Expand Down Expand Up @@ -144,18 +138,6 @@ impl Tile {
}
}

impl Direction {
fn advance(&self, pos: Pos) -> Option<Pos> {
Some(match self {
Self::Up if pos.y() > 0 => pos - vector!(0, 1),
Self::Down => pos + vector!(0, 1),
Self::Left if pos.x() > 0 => pos - vector!(1, 0),
Self::Right => pos + vector!(1, 0),
_ => return None,
})
}
}

#[cfg(test)]
mod test {
use common::Solution;
Expand Down
67 changes: 16 additions & 51 deletions aoc_2023/src/day_17.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use std::collections::{HashMap, VecDeque};
use common::{Answer, Solution};
use nd_vec::{vector, Vec2};

use crate::aoc_lib::direction::Direction;

type Pos = Vec2<usize>;

pub struct Day17;
Expand Down Expand Up @@ -34,16 +36,17 @@ fn pathfind(board: Vec<Vec<u8>>, min_dist: u8, max_dist: u8) -> u32 {
}

while let Some((cost, state)) = queue.pop_front() {
let mut push = |facing: Direction, turn_distance: u8| {
if let Some(pos) = facing.advance(state.pos) {
if pos.y() < board.len() && pos.x() < board[0].len() {
let state = State::new(pos, facing, turn_distance);
let cost = cost + board[pos.y()][pos.x()] as u32;

if !visited.contains_key(&state) || visited.get(&state).unwrap() > &cost {
queue.push_back((cost, state));
visited.insert(state, cost);
}
let mut explore = |facing: Direction, turn_distance: u8| {
if let Some(pos) = facing
.try_advance(state.pos)
.filter(|pos| pos.y() < board.len() && pos.x() < board[0].len())
{
let state = State::new(pos, facing, turn_distance);
let cost = cost + board[pos.y()][pos.x()] as u32;

if !visited.contains_key(&state) || visited.get(&state).unwrap() > &cost {
queue.push_back((cost, state));
visited.insert(state, cost);
}
}
};
Expand All @@ -54,12 +57,12 @@ fn pathfind(board: Vec<Vec<u8>>, min_dist: u8, max_dist: u8) -> u32 {
}

if state.turn_distance < max_dist {
push(state.facing, state.turn_distance + 1);
explore(state.facing, state.turn_distance + 1);
}

if state.turn_distance >= min_dist {
push(state.facing.turn_left(), 1);
push(state.facing.turn_right(), 1);
explore(state.facing.turn_left(), 1);
explore(state.facing.turn_right(), 1);
}
}

Expand Down Expand Up @@ -90,44 +93,6 @@ impl State {
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
enum Direction {
Up,
Down,
Left,
Right,
}

impl Direction {
fn advance(&self, pos: Pos) -> Option<Pos> {
Some(match self {
Self::Up if pos.y() > 0 => pos - vector!(0, 1),
Self::Down => pos + vector!(0, 1),
Self::Left if pos.x() > 0 => pos - vector!(1, 0),
Self::Right => pos + vector!(1, 0),
_ => return None,
})
}

fn turn_left(&self) -> Self {
match self {
Self::Up => Self::Left,
Self::Down => Self::Right,
Self::Left => Self::Down,
Self::Right => Self::Up,
}
}

fn turn_right(&self) -> Self {
match self {
Self::Up => Self::Right,
Self::Down => Self::Left,
Self::Left => Self::Up,
Self::Right => Self::Down,
}
}
}

#[cfg(test)]
mod test {
use common::Solution;
Expand Down

0 comments on commit 32dc239

Please sign in to comment.