summaryrefslogtreecommitdiff
path: root/day9/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'day9/src/main.rs')
-rw-r--r--day9/src/main.rs46
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 @@
1use std::fs;
2use std::path::Path;
3
4/* AOC21 Day 9: https://adventofcode.com/2021/day/9 */
5fn 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
14fn 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
25fn 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
36fn 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}