Skip to content

Commit

Permalink
feat: day 10
Browse files Browse the repository at this point in the history
  • Loading branch information
JosefKuchar committed Dec 10, 2024
1 parent 9e6a46e commit 184afee
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 10 deletions.
108 changes: 99 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ test_lib = []
chrono = { version = "0.4.38", optional = true }
dhat = { version = "0.3.3", optional = true }
itertools = "0.13.0"
pathfinding = "4.11.0"
pico-args = "0.5.0"
rayon = "1.10.0"
regex = "1.11.1"
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
| [Day 7](./src/bin/07.rs) | `1.7ms` | `86.1ms` |
| [Day 8](./src/bin/08.rs) | `55.8µs` | `136.5µs` |
| [Day 9](./src/bin/09.rs) | `942.7µs` | `122.7ms` |
| [Day 10](./src/bin/10.rs) | `530.9µs` | `284.2µs` |

**Total: 435.42ms**
**Total: 436.23ms**
<!--- benchmarking table --->

---
Expand Down
8 changes: 8 additions & 0 deletions data/examples/10.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
89010123
78121874
87430965
96549874
45678903
32019012
01329801
10456732
83 changes: 83 additions & 0 deletions src/bin/10.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
advent_of_code::solution!(10);

use pathfinding::prelude::dijkstra_all;

const DIRS: [(isize, isize); 4] = [(0, 1), (1, 0), (0, -1), (-1, 0)];

fn in_bounds(map: &[Vec<i32>], pos: (isize, isize)) -> bool {
pos.0 >= 0 && pos.1 >= 0 && pos.0 < map.len() as isize && pos.1 < map[0].len() as isize
}

pub fn successors(map: &[Vec<i32>], pos: (usize, usize)) -> Vec<((usize, usize), u32)> {
let mut res = Vec::new();
let val = map[pos.0][pos.1];
for dir in &DIRS {
let next = (pos.0 as isize + dir.0, pos.1 as isize + dir.1);
if in_bounds(map, next) {
let next_val = map[next.0 as usize][next.1 as usize];
if next_val - 1 == val {
res.push(((next.0 as usize, next.1 as usize), 1));
}
}
}
res
}

fn solve(input: &str, func: fn(map: &[Vec<i32>], pos: (usize, usize)) -> u32) -> Option<u32> {
let map: Vec<Vec<i32>> = input
.lines()
.map(|line| {
line.chars()
.map(|c| c.to_digit(10).unwrap() as i32)
.collect()
})
.collect();

let mut sum = 0;
for (i, row) in map.iter().enumerate() {
for (j, cell) in row.iter().enumerate() {
if *cell == 0 {
sum += func(&map, (i, j));
}
}
}
Some(sum)
}

pub fn part_one(input: &str) -> Option<u32> {
solve(input, |map, pos| {
dijkstra_all(&pos, |&pos| successors(map, pos))
.iter()
.filter(|((i, j), _)| map[*i][*j] == 9)
.count() as u32
})
}

fn find_recursive(map: &[Vec<i32>], pos: (usize, usize)) -> u32 {
if map[pos.0][pos.1] == 9 {
return 1;
}
let next = successors(map, pos);
next.iter().map(|(pos, _)| find_recursive(map, *pos)).sum()
}

pub fn part_two(input: &str) -> Option<u32> {
solve(input, find_recursive)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_part_one() {
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(36));
}

#[test]
fn test_part_two() {
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(81));
}
}

0 comments on commit 184afee

Please sign in to comment.