summaryrefslogtreecommitdiff
path: root/2024_rust/src
diff options
context:
space:
mode:
authorGuillermo Ramos2024-12-10 19:56:19 +0100
committerGuillermo Ramos2024-12-11 09:56:58 +0100
commita360df726d04bf49fc8a06fdcbf668f1fea98aff (patch)
treedaf394808d08f61d9af227eddf8bec0db036cee3 /2024_rust/src
parent160caef50246ac9a62f596522598b1dca3fabb29 (diff)
downloadAoC-a360df726d04bf49fc8a06fdcbf668f1fea98aff.tar.gz
2024.10
Diffstat (limited to '2024_rust/src')
-rw-r--r--2024_rust/src/bin/day10.rs68
-rw-r--r--2024_rust/src/lib.rs13
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;