diff options
Diffstat (limited to 'day9/src/main.rs')
-rw-r--r-- | day9/src/main.rs | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/day9/src/main.rs b/day9/src/main.rs new file mode 100644 index 0000000..9f15635 --- /dev/null +++ b/day9/src/main.rs | |||
@@ -0,0 +1,46 @@ | |||
1 | use std::fs; | ||
2 | use std::path::Path; | ||
3 | |||
4 | /* AOC21 Day 9: https://adventofcode.com/2021/day/9 */ | ||
5 | fn main() { | ||
6 | let input = Path::new("resources").join("input.txt"); | ||
7 | let content = fs::read_to_string(input).expect("Unable to read input file"); | ||
8 | let width = content.lines().next().expect("Empty input").len(); | ||
9 | let heightmap: Vec<u8> = content.lines().flat_map(|l| l.bytes().map(|c| c-b'0')).collect(); | ||
10 | println!("Ex1: The risk level is {}", risk_level(&heightmap, width)); | ||
11 | println!("Ex2: The result is {}", find_basins(&heightmap, width)); | ||
12 | } | ||
13 | |||
14 | fn risk_level(hm: &[u8], w: usize) -> u32 { | ||
15 | (0..hm.len()).map(|i| | ||
16 | if ( i < w || hm[i-w] > hm[i] ) && | ||
17 | ( i+w >= hm.len() || hm[i+w] > hm[i] ) && | ||
18 | ( i%w == 0 || hm[i-1] > hm[i] ) && | ||
19 | ( (i+1)%w == 0 || hm[i+1] > hm[i] ) { | ||
20 | 1 + hm[i] as u32 | ||
21 | } else { 0 } | ||
22 | ).sum() | ||
23 | } | ||
24 | |||
25 | fn find_basins(hm: &[u8], w: usize) -> u32 { | ||
26 | let mut hmask = vec![false;hm.len()]; | ||
27 | let mut basins: Vec<u32> = vec![]; | ||
28 | for i in 0..hm.len() { | ||
29 | let size = propagate_basin(hm, &mut hmask, i, w); | ||
30 | if size > 0 { basins.push(size); } | ||
31 | } | ||
32 | basins.sort_by(|a,b| b.cmp(a)); | ||
33 | basins.iter().take(3).product() | ||
34 | } | ||
35 | |||
36 | fn propagate_basin(hm: &[u8], hmask: &mut [bool], i: usize, w: usize) -> u32 { | ||
37 | if !hmask[i] && hm[i] != 9 { | ||
38 | hmask[i] = true; | ||
39 | 1 + if i >= w { propagate_basin(hm, hmask, i-w, w) } else { 0 } + | ||
40 | if i+w < hm.len() { propagate_basin(hm, hmask, i+w, w) } else { 0 } + | ||
41 | if i%w != 0 { propagate_basin(hm, hmask, i-1, w) } else { 0 } + | ||
42 | if (i+1)%w != 0 { propagate_basin(hm, hmask, i+1, w) } else { 0 } | ||
43 | } else { | ||
44 | 0 | ||
45 | } | ||
46 | } | ||