-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday10.rs
39 lines (31 loc) · 1.19 KB
/
day10.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
use std::fs::read_to_string;
use rustc_hash::FxHashSet;
use crate::etc::{Matrix, Pos};
use crate::{Solution, SolutionPair};
///////////////////////////////////////////////////////////////////////////////
pub fn solve() -> SolutionPair {
let input = read_to_string("input/day10.txt").unwrap();
let grid = Matrix::map_digits(&input);
let scores = grid.find_all(0).map(|p| trailhead_score(&grid, p));
let (sol1, sol2) = scores.reduce(|prev, next| (prev.0 + next.0, prev.1 + next.1)).unwrap();
(Solution::from(sol1), Solution::from(sol2))
}
fn trailhead_score(grid: &Matrix<u8>, start: Pos) -> (usize, usize) {
let mut uniq = FxHashSet::default();
let total = dfs(grid, start, &mut uniq);
(uniq.len(), total)
}
fn dfs(grid: &Matrix<u8>, pos: Pos, unique: &mut FxHashSet<Pos>) -> usize {
let val = grid[pos];
let next = neighbors(grid, pos, val + 1);
if val == 8 {
unique.extend(next.iter());
return next.len();
}
next.into_iter().map(|p| dfs(grid, p, unique)).sum()
}
fn neighbors(grid: &Matrix<u8>, pos: Pos, expect: u8) -> Vec<Pos> {
pos.neighbors().into_iter()
.filter(|&p| grid.get_or(p, u8::MAX) == expect)
.collect()
}