Skip to content

Commit

Permalink
Add ordinal directions to aoc_lib
Browse files Browse the repository at this point in the history
  • Loading branch information
connorslade committed Dec 4, 2024
1 parent d9ec36e commit e492574
Show file tree
Hide file tree
Showing 12 changed files with 83 additions and 75 deletions.
2 changes: 1 addition & 1 deletion aoc_2021/src/day_15.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::collections::BinaryHeap;
use hashbrown::HashMap;
use nd_vec::{vector, Vector};

use aoc_lib::{direction::Direction, matrix::Matrix};
use aoc_lib::{direction::cardinal::Direction, matrix::Matrix};
use common::{solution, Answer};

solution!("Chiton", 15);
Expand Down
2 changes: 1 addition & 1 deletion aoc_2023/src/day_10.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::HashSet;

use nd_vec::{vector, Vec2};

use aoc_lib::direction::Direction;
use aoc_lib::direction::cardinal::Direction;
use common::{solution, Answer};

type Pos = Vec2<usize>;
Expand Down
2 changes: 1 addition & 1 deletion aoc_2023/src/day_16.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::HashSet;

use aoc_lib::{direction::Direction, matrix::Matrix};
use aoc_lib::{direction::cardinal::Direction, matrix::Matrix};
use common::{solution, Answer};
use nd_vec::{vector, Vec2};

Expand Down
2 changes: 1 addition & 1 deletion aoc_2023/src/day_17.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{
collections::{BinaryHeap, HashMap},
};

use aoc_lib::{direction::Direction, matrix::Matrix};
use aoc_lib::{direction::cardinal::Direction, matrix::Matrix};
use common::{solution, Answer};
use nd_vec::{vector, Vec2};

Expand Down
2 changes: 1 addition & 1 deletion aoc_2023/src/day_18.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use aoc_lib::direction::Direction;
use aoc_lib::direction::cardinal::Direction;
use common::{solution, Answer};
use nd_vec::vector;

Expand Down
2 changes: 1 addition & 1 deletion aoc_2023/src/day_21.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::HashSet;

use aoc_lib::{direction::Direction, matrix::Matrix};
use aoc_lib::{direction::cardinal::Direction, matrix::Matrix};
use common::{solution, Answer};
use nd_vec::{vector, Vec2};

Expand Down
2 changes: 1 addition & 1 deletion aoc_2023/src/day_23.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{
convert::identity,
};

use aoc_lib::{direction::Direction, matrix::Matrix};
use aoc_lib::{direction::cardinal::Direction, matrix::Matrix};
use common::{solution, Answer};
use nd_vec::{vector, Vec2};

Expand Down
93 changes: 26 additions & 67 deletions aoc_2024/src/day_04.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,51 @@
use aoc_lib::matrix::Matrix;
use std::convert::identity;

use aoc_lib::{direction::ordinal::Direction, matrix::Matrix};
use common::{solution, Answer};
use nd_vec::{vector, Vector};
use nd_vec::vector;

solution!("Ceres Search", 4);

fn part_a(input: &str) -> Answer {
let matrix = Matrix::new_chars(input, |x| x);
let matrix = Matrix::new_chars(input, identity);
let mut count = 0;

for y in 0..matrix.size.y() {
for x in 0..matrix.size.x() {
let start = vector!(x, y);
if *matrix.get(start).unwrap() != 'X' {
continue;
}

for dir in Direction::ALL {
let mut pos = start.clone();
let mut word = String::new();
for _ in 0..4 {
if let Some(&chr) = matrix.get(pos) {
word.push(chr);
} else {
break;
}
for expected in ['M', 'A', 'S'] {
let next = dir.try_advance(pos);
let Some(next) = next else { break };
pos = next;

let Some(next) = dir.try_advance(pos) else {
let Some(&chr) = matrix.get(pos) else { break };
if chr != expected {
break;
};
pos = next;
}
}

if word == "XMAS" {
count += 1;
}
count += 1;
}
}
}

count.into()
}

/// The directions to advance from the middle 'A' for each MAS instance.
const MAS_DIRECTIONS: [[Direction; 2]; 2] = [
[Direction::NorthEast, Direction::SouthWest],
[Direction::SouthEast, Direction::NorthWest],
];

fn part_b(input: &str) -> Answer {
let matrix = Matrix::new_chars(input, |x| x);
let matrix = Matrix::new_chars(input, identity);
let mut count = 0;

for y in 0..matrix.size.y() {
Expand All @@ -48,19 +55,10 @@ fn part_b(input: &str) -> Answer {
continue;
}

let directions = [
[Direction::NorthEast, Direction::SouthWest],
[Direction::SouthEast, Direction::NorthWest],
// should have a 'M' and a 'S'
];

for mas in directions {
for mas in MAS_DIRECTIONS {
let (mut m, mut s) = (false, false);
for dir in mas {
let Some(pos) = dir.try_advance(start) else {
continue 'outer;
};
let Some(&chr) = matrix.get(pos) else {
let Some(&chr) = dir.try_advance(start).and_then(|x| matrix.get(x)) else {
continue 'outer;
};

Expand All @@ -80,45 +78,6 @@ fn part_b(input: &str) -> Answer {
count.into()
}

#[derive(Debug)]
enum Direction {
North,
NorthEast,
East,
SouthEast,
South,
SouthWest,
West,
NorthWest,
}

impl Direction {
pub const ALL: [Direction; 8] = [
Direction::North,
Direction::NorthEast,
Direction::East,
Direction::SouthEast,
Direction::South,
Direction::SouthWest,
Direction::West,
Direction::NorthWest,
];

pub fn try_advance(&self, pos: Vector<usize, 2>) -> Option<Vector<usize, 2>> {
Some(match self {
Self::North => vector!(pos.x(), pos.y() + 1),
Self::NorthEast => vector!(pos.x() + 1, pos.y() + 1),
Self::East => vector!(pos.x() + 1, pos.y()),
Self::SouthEast if pos.y() > 0 => vector!(pos.x() + 1, pos.y() - 1),
Self::South if pos.y() > 0 => vector!(pos.x(), pos.y() - 1),
Self::SouthWest if pos.x() > 0 && pos.y() > 0 => vector!(pos.x() - 1, pos.y() - 1),
Self::West if pos.x() > 0 => vector!(pos.x() - 1, pos.y()),
Self::NorthWest if pos.x() > 0 => vector!(pos.x() - 1, pos.y() + 1),
_ => return None,
})
}
}

#[cfg(test)]
mod test {
use indoc::indoc;
Expand Down
File renamed without changes.
2 changes: 2 additions & 0 deletions aoc_lib/src/direction/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod cardinal;
pub mod ordinal;
47 changes: 47 additions & 0 deletions aoc_lib/src/direction/ordinal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use nd_vec::{vector, Vec2};
use num_traits::Num;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Direction {
North,
NorthEast,
East,
SouthEast,
South,
SouthWest,
West,
NorthWest,
}

impl Direction {
pub const ALL: [Direction; 8] = [
Direction::North,
Direction::NorthEast,
Direction::East,
Direction::SouthEast,
Direction::South,
Direction::SouthWest,
Direction::West,
Direction::NorthWest,
];

pub fn try_advance<T: Num + Copy + PartialOrd>(&self, pos: Vec2<T>) -> Option<Vec2<T>> {
Some(match self {
Self::North => vector!(pos.x(), pos.y() + T::one()),
Self::NorthEast => vector!(pos.x() + T::one(), pos.y() + T::one()),
Self::East => vector!(pos.x() + T::one(), pos.y()),
Self::SouthEast if pos.y() > T::zero() => {
vector!(pos.x() + T::one(), pos.y() - T::one())
}
Self::South if pos.y() > T::zero() => vector!(pos.x(), pos.y() - T::one()),
Self::SouthWest if pos.x() > T::zero() && pos.y() > T::zero() => {
vector!(pos.x() - T::one(), pos.y() - T::one())
}
Self::West if pos.x() > T::zero() => vector!(pos.x() - T::one(), pos.y()),
Self::NorthWest if pos.x() > T::zero() => {
vector!(pos.x() - T::one(), pos.y() + T::one())
}
_ => return None,
})
}
}
2 changes: 1 addition & 1 deletion aoc_lib/src/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl<T> Matrix<T> {
}

pub fn new_chars(input: &str, parse: fn(char) -> T) -> Self {
let mut data = Vec::new();
let mut data = Vec::with_capacity(input.len());
let mut size = vector!(0, 0);

for line in input.lines() {
Expand Down

0 comments on commit e492574

Please sign in to comment.