104 lines
3.2 KiB
Rust
104 lines
3.2 KiB
Rust
use std::fs::File;
|
|
use std::io::{BufReader};
|
|
use std::io::prelude::*;
|
|
|
|
const RADIX: u32 = 10;
|
|
|
|
static mut visited: Vec<Vec<bool>> = Vec::new();
|
|
|
|
fn main(){
|
|
let file = File::open("./input.txt").expect("Read failed");
|
|
let reader = BufReader::new(file);
|
|
|
|
let mut line_vec: Vec<Vec<u32>> = Vec::new();
|
|
|
|
for line in reader.lines(){
|
|
let line_as_string = line.unwrap();
|
|
let line_as_int_vec = line_as_string.chars().map(|x| x.to_digit(RADIX).unwrap()).collect::<Vec<u32>>();
|
|
line_vec.push(line_as_int_vec);
|
|
|
|
}
|
|
|
|
let height = line_vec.len();
|
|
let width = line_vec[0].len();
|
|
|
|
let mut danger_value = 0;
|
|
|
|
let mut low_points: Vec<(usize, usize)> = Vec::new();
|
|
|
|
for line_nr in 0..height {
|
|
for col_nr in 0..width {
|
|
let upper = if line_nr > 0 {line_vec[line_nr - 1][col_nr]} else { 99 };
|
|
let lower = if line_nr < height - 1 {line_vec[line_nr + 1][col_nr]} else { 99 };
|
|
let left = if col_nr > 0 {line_vec[line_nr][col_nr - 1]} else { 99 };
|
|
let right = if col_nr < width - 1 {line_vec[line_nr][col_nr + 1]} else { 99 };
|
|
let val = line_vec[line_nr][col_nr];
|
|
if val < upper && val < lower && val < left && val < right {
|
|
danger_value += 1 + val;
|
|
low_points.push((line_nr, col_nr));
|
|
}
|
|
}
|
|
}
|
|
|
|
for _ in 0..height {
|
|
unsafe { visited.push(vec![false; width]); }
|
|
}
|
|
|
|
|
|
|
|
let mut basins: Vec<Vec<(i32, i32)>> = Vec::new();
|
|
let mut sizes: Vec<i32> = Vec::new();
|
|
|
|
for point in low_points {
|
|
let test = get_neighbours(point.0 as i32, point.1 as i32, height, width, &line_vec);
|
|
if test != None {basins.push(test.expect("msg"));}
|
|
}
|
|
|
|
unsafe {
|
|
for bas in basins {
|
|
println!("Size of basin: {}", bas.len());
|
|
sizes.push(bas.len() as i32);
|
|
}
|
|
}
|
|
|
|
sizes.sort();
|
|
|
|
let mul_result = sizes[sizes.len()-1] * sizes[sizes.len()-2] * sizes[sizes.len()-3];
|
|
|
|
println!("Danger value: {}", danger_value);
|
|
println!("Multiplication result: {}", mul_result);
|
|
|
|
}
|
|
|
|
fn get_neighbours(line_nr: i32, col_nr: i32, height: usize, width: usize, line_vec: &Vec<Vec<u32>>) -> Option<Vec<(i32, i32)>>{
|
|
unsafe {
|
|
if ( line_nr < 0 || line_nr > (height-1) as i32) || ( col_nr < 0 || col_nr > (width-1) as i32) {
|
|
return None;
|
|
}
|
|
if visited[line_nr as usize][col_nr as usize] {
|
|
return None;
|
|
}
|
|
if line_vec[line_nr as usize][col_nr as usize] == 9 {
|
|
return None;
|
|
}
|
|
visited[line_nr as usize][col_nr as usize] = true;
|
|
let mut result_vec: Vec<(i32, i32)> = Vec::new();
|
|
let l_res = get_neighbours(line_nr, col_nr-1, height, width, &line_vec);
|
|
let r_res = get_neighbours(line_nr, col_nr+1, height, width, &line_vec);
|
|
let u_res = get_neighbours(line_nr-1, col_nr, height, width, &line_vec);
|
|
let d_res = get_neighbours(line_nr+1, col_nr, height, width, &line_vec);
|
|
if l_res != None { result_vec.append(&mut l_res?); }
|
|
if r_res != None { result_vec.append(&mut r_res?); }
|
|
if u_res != None { result_vec.append(&mut u_res?); }
|
|
if d_res != None { result_vec.append(&mut d_res?); }
|
|
|
|
|
|
result_vec.push((line_nr, col_nr));
|
|
|
|
|
|
|
|
return Some(result_vec);
|
|
}
|
|
|
|
|
|
} |