advent-of-code-2021/day15/src/main.rs

64 lines
2.0 KiB
Rust
Raw Normal View History

use std::{fs, env, collections::HashMap};
fn read_input(path: &str) -> String {
return fs::read_to_string(path).expect("Cannot read file.");
}
fn parse_input(s: &str) -> Vec<Vec<u32>> {
return s.lines()
.map(|l| l.chars().filter_map(|e| e.to_digit(10)).collect())
.collect();
}
fn expand_map(m: &Vec<Vec<u32>>) -> Vec<Vec<u32>> {
let mut t = vec![];
for l in 0..(5 * m.len()) {
t.push(vec![]);
for c in 0..(5 * m.len()) {
let x = (m[l % m.len()][c % m[0].len()] + (l / m.len() + c / m[0].len()) as u32) % 9;
t[l].push(if x == 0 { 9 } else { x });
}
}
return t;
}
fn get_shortest_risk(m: &Vec<Vec<u32>>, mut l: usize, mut c: usize) -> u32 {
let mut w = HashMap::new();
w.insert((l, c), 0);
let mut q = vec![(0, l, c)];
while !q.is_empty() {
let e = q.pop().unwrap();
l = e.1;
c = e.2;
let z = *w.get(&(l, c)).unwrap();
let mut p = vec![];
if c > 0 { p.push((l, c - 1)); }
if l > 0 { p.push((l - 1, c)); }
if c < m[l].len() - 1 { p.push((l, c + 1)); }
if l < m.len() - 1 { p.push((l + 1, c)); }
while !p.is_empty() {
let a = p.pop().unwrap();
let x = *w.get(&a).unwrap_or(&u32::MAX);
if x > z + m[a.0][a.1] {
w.insert(a, z + m[a.0][a.1]);
q.push((z + m[a.0][a.1], a.0, a.1));
}
}
q.sort_by(|a, b| b.cmp(a));
}
return *w.get(&(m.len() - 1, m[m.len() - 1].len() - 1)).unwrap_or(&u32::MAX);
}
fn main() {
let args: Vec<String> = env::args().collect();
for arg in args.iter().skip(1) {
let input = read_input(&arg);
let vec_in = parse_input(&input);
let exp = expand_map(&vec_in);
println!("[{}]", &arg);
println!("\t[Part 1] => Answer is '{}'.", get_shortest_risk(&vec_in, 0, 0));
println!("\t[Part 2] => Answer is '{}'.", get_shortest_risk(&exp, 0, 0));
}
}