Rust challenge 74/100 - aoc 2022 day12
Table of content
What is this
The rules of the game are explained in my original.
74th Challenge
Challenge
So I’m a bit behind but I’m keen to solve them all - so here goes day 12 of AoC🎅🦀
Solution
Here is solution of part 1 and 2. Part 1 confused me for a bit. I knew I had to use breadth first BFS tree traversal but the code wouldn’t stop. The issue was I had fergotten to add the linesif !queue.contains(&new_point){
which made my queue grow to giant sizes. First I thought I needed to use Dijkstra but that was not the case.
use std::collections::{
HashSet,
VecDeque
};
fn main() {
let output = find_shortest_path(include_str!("../input.txt"),'S');
println!("Ans1: {:?}", output);
let mut output = find_shortest_path(include_str!("../input.txt"),'a');
output.sort();
println!("Ans: {:?}", output.first());
}
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
struct Point {
x: usize,
y: usize,
}
fn find_shortest_path(input: &str,starting_char:char) -> Vec<u64> {
let mut grid: Vec<i64> = vec![];
let row_size: usize = input.lines().next().unwrap().len();
let col_size: usize = input.lines().count();
let mut starting_points =vec![];
for line in input.lines() {
for c in line.trim().chars() {
match c {
_ if c == starting_char || c == 'S' => {
starting_points.push(grid.len());
if c == 'S' {
grid.push(('a' as u8 - 1) as i64)
}else{
grid.push(c as i64)
}
},
'a'..='z' => grid.push(c as i64),
'E' => grid.push(('z' as u8 + 1) as i64),
_ => (),
}
}
}
let mut depths:Vec<u64> = vec![];
for starting_point in starting_points {
let starting_point = Point { x: starting_point%row_size, y: starting_point/row_size };
let mut queue: VecDeque<Point> = VecDeque::new();
queue.push_back(starting_point);
let mut visited = HashSet::new();
let mut current_depth:usize = 0;
let mut finished = false;
while !queue.is_empty() && !finished {
let mut level_size:usize = queue.len();
while level_size > 0 {
level_size -= 1;
let current_point = queue.pop_front().unwrap();
let current_index = current_point.x + current_point.y*row_size;
let current_char = grid[current_index];
if current_char == ('z' as u8+1) as i64 {
depths.push(current_depth as u64);
finished = true;
} else {
visited.insert(current_index);
if current_point.x > 0 && (grid[current_point.x-1 + current_point.y*row_size]-current_char) <=1 {
if !visited.contains(&(current_point.x-1 + current_point.y*row_size)) {
let new_point = Point { x: current_point.x - 1, y: current_point.y };
if !queue.contains(&new_point){
queue.push_back(new_point);
}
}
}
if current_point.x < row_size - 1 && (grid[current_point.x+1 + current_point.y*row_size]-current_char) <= 1 {
if !visited.contains(&(current_point.x+1 + current_point.y*row_size)) {
let new_point = Point { x: current_point.x + 1, y: current_point.y };
if !queue.contains(&new_point){
queue.push_back(new_point);
}
}
}
if current_point.y > 0 && (grid[current_point.x + (current_point.y-1)*row_size]-current_char) <= 1{
if !visited.contains(&(current_point.x + (current_point.y-1)*row_size)) {
let new_point = Point { x: current_point.x, y: current_point.y - 1 };
if !queue.contains(&new_point){
queue.push_back(new_point);
}
}
}
if current_point.y < col_size - 1 && (grid[current_point.x+(current_point.y+1)*row_size]-current_char) <= 1 {
if !visited.contains(&(current_point.x+(current_point.y+1)*row_size)) {
let new_point = Point { x: current_point.x, y: current_point.y + 1 };
if !queue.contains(&new_point){
queue.push_back(new_point);
}
}
}
}
}
current_depth+=1;
}
}
depths
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT: &str = "Sabqponm
abcryxxl
accszExk
acctuvwj
abdefghi";
#[test]
fn it_works() {
let output = find_shortest_path(INPUT,'S');
assert_eq!(output, vec![31]);
}
}