diff options
author | Guillermo Ramos | 2024-12-10 19:56:19 +0100 |
---|---|---|
committer | Guillermo Ramos | 2024-12-11 09:56:58 +0100 |
commit | a360df726d04bf49fc8a06fdcbf668f1fea98aff (patch) | |
tree | daf394808d08f61d9af227eddf8bec0db036cee3 /2024_rust/src | |
parent | 160caef50246ac9a62f596522598b1dca3fabb29 (diff) | |
download | AoC-a360df726d04bf49fc8a06fdcbf668f1fea98aff.tar.gz |
2024.10
Diffstat (limited to '2024_rust/src')
-rw-r--r-- | 2024_rust/src/bin/day10.rs | 68 | ||||
-rw-r--r-- | 2024_rust/src/lib.rs | 13 |
2 files changed, 81 insertions, 0 deletions
diff --git a/2024_rust/src/bin/day10.rs b/2024_rust/src/bin/day10.rs new file mode 100644 index 0000000..3c208bd --- /dev/null +++ b/2024_rust/src/bin/day10.rs @@ -0,0 +1,68 @@ +use aoc2024::matrix; +use std::collections::HashSet; + +static AROUND_DELTAS: [(isize, isize); 4] = [(-1, 0), (0, -1), (0, 1), (1, 0)]; + +type Matrix = matrix::Matrix<u32>; +type Trailhead = matrix::Pos; + +fn trailheads(m: &Matrix) -> Vec<Trailhead> { + let mut result: Vec<Trailhead> = vec![]; + for i in 0..m.limit.0 { + for j in 0..m.limit.1 { + let pos = (i, j); + if m.get(pos) == &0 { + result.push(pos); + } + } + } + result +} + +fn reachable(m: &Matrix, pos: matrix::Pos) -> HashSet<matrix::Pos> { + let height = m.get(pos); + AROUND_DELTAS + .iter() + .filter_map(|&d| m.pos_move(pos, d)) + .filter(|&p| *m.get(p) == height + 1) + .collect() +} + +fn score1(m: &Matrix, th: Trailhead) -> u32 { + let mut heads: HashSet<matrix::Pos> = HashSet::new(); + heads.insert(th); + let mut height = 0; + while height < 9 { + heads = heads.into_iter().flat_map(|th| reachable(m, th)).collect(); + height += 1; + } + heads.len() as u32 +} + +fn p1(input: &str) -> String { + let m: Matrix = matrix::Matrix::new(input, |c| c.to_digit(10).unwrap()); + let result: u32 = trailheads(&m).iter().map(|&th| score1(&m, th)).sum(); + + result.to_string() +} + +fn score2(m: &Matrix, th: Trailhead) -> u32 { + let mut heads: Vec<matrix::Pos> = vec![th]; + let mut height = 0; + while height < 9 { + heads = heads.into_iter().flat_map(|th| reachable(m, th)).collect(); + height += 1; + } + heads.len() as u32 +} + +fn p2(input: &str) -> String { + let m: Matrix = matrix::Matrix::new(input, |c| c.to_digit(10).unwrap()); + let result: u32 = trailheads(&m).iter().map(|&th| score2(&m, th)).sum(); + + result.to_string() +} + +fn main() { + aoc2024::run_day("10", Some(p1), Some(p2)); +} diff --git a/2024_rust/src/lib.rs b/2024_rust/src/lib.rs index c034fea..ea6f7d6 100644 --- a/2024_rust/src/lib.rs +++ b/2024_rust/src/lib.rs @@ -1,5 +1,6 @@ pub mod matrix { pub type Pos = (usize, usize); + pub type PosDelta = (isize, isize); #[derive(Clone)] pub struct Matrix<T> { @@ -27,6 +28,18 @@ pub mod matrix { pub fn set(&mut self, (x, y): Pos, dot: T) { self.dots[x][y] = dot; } + + pub fn pos_move(&self, (x, y): Pos, (dx, dy): PosDelta) -> Option<Pos> { + let x2 = x as isize + dx; + if x2 < 0 || x2 >= self.limit.0 as isize { + return None; + } + let y2 = y as isize + dy; + if y2 < 0 || y2 >= self.limit.1 as isize { + return None; + } + Some((x2 as usize, y2 as usize)) + } } use std::fmt; |