Skip to content

Commit

Permalink
[2024] Cleanup day 10
Browse files Browse the repository at this point in the history
  • Loading branch information
connorslade committed Dec 10, 2024
1 parent 9f14acb commit 1a82e61
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 54 deletions.
4 changes: 2 additions & 2 deletions aoc_2024/src/day_07.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fn solve(input: &str, part_b: bool) -> u64 {
// For part a, we check if its valid using `is_valid` with part_b = false,
// because an equation that is valid for part a is must be valid for part b,
// we can get a small speedup by only doing the more intense part_b = true
// check if needed.
// check if needed.
problem
.cases
.into_iter()
Expand Down Expand Up @@ -85,7 +85,7 @@ impl TestCase {
}

// Increments the leftmost operation, carrying if it exceeds 1 for
// part a or 2 for part b.
// part a or 2 for part b.
for op in ops.iter_mut() {
*op += 1;
if *op <= (1 + part_b as usize) {
Expand Down
74 changes: 23 additions & 51 deletions aoc_2024/src/day_10.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,18 @@ use nd_vec::Vec2;
solution!("Hoof It", 10);

fn part_a(input: &str) -> Answer {
let map = Map::parse(input);
map.trailheads()
.into_iter()
.map(|x| map.score(x))
.sum::<usize>()
.into()
solve(input, false).into()
}

fn part_b(input: &str) -> Answer {
solve(input, true).into()
}

fn solve(input: &str, part_b: bool) -> usize {
let map = Map::parse(input);
map.trailheads()
.into_iter()
.map(|x| map.rating(x))
.map(|x| map.score(x, !part_b))
.sum::<usize>()
.into()
}

struct Map {
Expand All @@ -34,15 +31,17 @@ impl Map {
Self { board }
}

fn trailheads(&self) -> Vec<Vec2<usize>> {
// Find the coordinates of all 0s
fn trailheads(&self) -> impl Iterator<Item = Vec2<usize>> + use<'_> {
self.board
.iter()
.filter(|(_, &tile)| tile == 0)
.map(|(pos, _)| pos)
.collect()
}

fn score(&self, pos: Vec2<usize>) -> usize {
// Simple BFS for pathfinding, where we don't avoid going to already
// explored tiles if on part B.
fn score(&self, pos: Vec2<usize>, no_repeats: bool) -> usize {
let mut queue = VecDeque::new();
let mut seen = HashSet::new();

Expand All @@ -52,49 +51,22 @@ impl Map {
let mut score = 0;
while let Some(pos) = queue.pop_front() {
let value = *self.board.get(pos).unwrap();
if value == 9 {
score += 1;
}

for dir in Direction::ALL {
if let Some(next) = dir.try_advance(pos) {
if self.board.contains(next)
&& *self.board.get(next).unwrap() == value + 1
&& seen.insert(next)
{
queue.push_back(next);
}
}
}
score += (value == 9) as usize;

queue.extend(
Direction::ALL
.iter()
.filter_map(|&dir| dir.try_advance(pos))
.filter(|&next| {
self.board.contains(next)
&& *self.board.get(next).unwrap() == value + 1
&& (!no_repeats || seen.insert(next))
}),
);
}

score
}

fn rating(&self, pos: Vec2<usize>) -> usize {
fn inner(board: &Matrix<u32>, pos: Vec2<usize>, mut seen: HashSet<Vec2<usize>>) -> usize {
let value = *board.get(pos).unwrap();
if value == 9 {
return 1;
}

let mut sum = 0;
for dir in Direction::ALL {
if let Some(next) = dir.try_advance(pos) {
if board.contains(next)
&& *board.get(next).unwrap() == value + 1
&& seen.insert(next)
{
sum += inner(board, next, seen.clone());
}
}
}

sum
}

inner(&self.board, pos, HashSet::new())
}
}

#[cfg(test)]
Expand Down
1 change: 0 additions & 1 deletion common/src/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@ pub fn load_raw(year: u16, day: u32) -> io::Result<String> {
let file = format!("data/{year}/{:02}.txt", day);
fs::read_to_string(file)
}

0 comments on commit 1a82e61

Please sign in to comment.