advent_of_code_2022/aoc_12a/src/main.rs

117 lines
3.4 KiB
Rust

use std::fs::File;
use std::io::{self, BufRead};
use std::path::Path;
use std::collections::HashSet;
#[derive(Debug)]
struct Cell {
altitude: u8,
score: Option<u32>,
}
impl Cell {
pub fn new(altitude: u8) -> Self {
Self {
altitude,
score: None,
}
}
}
fn print_map(map: &Vec<Vec<Cell>>) {
for y in map.iter() {
for x in y.iter() {
let c;
match x.score {
Some(n) => {
let m = (n % 62) as u8;
if m < 26 {
c = m + b'a';
}
else if m < 52 {
c = m + b'A' - 26;
}
else {
c = m + b'0' - 52;
}
},
None => c = b'#'
};
print!("{}", c as char);
}
println!("");
}
}
fn main() {
let file_path = String::from("input");
let mut map = Vec::<Vec<Cell>>::new();
let mut start_coor: (usize, usize) = (0, 0);
let mut end_coor: (usize, usize) = (0, 0);
println!("In file {}", file_path);
if let Ok(lines) = read_lines(file_path) {
// Consumes the iterator, returns an (Optional) String
for (y, line) in lines.enumerate() {
if let Ok(ip) = line {
map.push(ip.bytes().enumerate().map(|(x, byte)| match byte {
b'a'..=b'z' => Cell::new(byte - b'a'),
b'S' => {
start_coor = (x, y);
Cell::new(0)
},
b'E' => {
end_coor = (x, y);
Cell::new(25)
}
_ => panic!("Parse error"),
}).collect());
}
}
}
let height = map.len();
let width = map[0].len();
let mut cursors = vec![start_coor];
let mut score = 0;
while !cursors.is_empty() {
let mut new_cursors = HashSet::<(usize, usize)>::new();
for cursor in cursors {
let (x, y) = cursor;
let altitude = map[y][x].altitude;
match map[y][x].score {
Some(_) => (),
None => {
map[y][x].score = Some(score);
if x + 1 < width && altitude + 1 >= map[y][x + 1].altitude {
new_cursors.insert((x + 1, y));
}
if x > 0 && altitude + 1 >= map[y][x - 1].altitude {
new_cursors.insert((x - 1, y));
}
if y + 1 < height && altitude + 1 >= map[y + 1][x].altitude {
new_cursors.insert((x, y + 1));
}
if y > 0 && altitude + 1 >= map[y - 1][x].altitude {
new_cursors.insert((x, y - 1));
}
},
};
}
score += 1;
cursors = Vec::<(usize, usize)>::new();
for cursor in new_cursors {
cursors.push(cursor);
}
}
print_map(&map);
println!("{}", map[end_coor.1][end_coor.0].score.unwrap());
}
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
where P: AsRef<Path>, {
let file = File::open(filename)?;
Ok(io::BufReader::new(file).lines())
}