Day 12, puzzle 1
This commit is contained in:
		
							
								
								
									
										9
									
								
								src/bin/d12p1.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/bin/d12p1.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					use aoc22::{day12, util};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn main() {
 | 
				
			||||||
 | 
					    let heightmap = day12::parse_heightmap(&util::parse_input());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let dist = day12::path_steps(&heightmap).expect("No path found!?");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    println!("Distance to target is {}", dist);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										99
									
								
								src/day12.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/day12.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,99 @@
 | 
				
			|||||||
 | 
					use std::collections::VecDeque;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use itertools::Itertools;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub type Coord = (usize, usize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
					pub struct Heightmap {
 | 
				
			||||||
 | 
					    pub map: Vec<Vec<usize>>,
 | 
				
			||||||
 | 
					    pub rows: usize,
 | 
				
			||||||
 | 
					    pub cols: usize,
 | 
				
			||||||
 | 
					    pub start: Coord,
 | 
				
			||||||
 | 
					    pub target: Coord,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn parse_heightmap(input: &String) -> Heightmap {
 | 
				
			||||||
 | 
					    let mut start = (usize::MAX, usize::MAX);
 | 
				
			||||||
 | 
					    let mut target = (usize::MAX, usize::MAX);
 | 
				
			||||||
 | 
					    let map = input
 | 
				
			||||||
 | 
					        .lines()
 | 
				
			||||||
 | 
					        .enumerate()
 | 
				
			||||||
 | 
					        .map(|(row, l)| {
 | 
				
			||||||
 | 
					            l.as_bytes()
 | 
				
			||||||
 | 
					                .iter()
 | 
				
			||||||
 | 
					                .enumerate()
 | 
				
			||||||
 | 
					                .map(|(col, c)| {
 | 
				
			||||||
 | 
					                    if *c == ('S' as u8) {
 | 
				
			||||||
 | 
					                        start = (row, col);
 | 
				
			||||||
 | 
					                        0
 | 
				
			||||||
 | 
					                    } else if *c == ('E' as u8) {
 | 
				
			||||||
 | 
					                        target = (row, col);
 | 
				
			||||||
 | 
					                        25
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        (c - ('a' as u8)) as usize
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					                .collect_vec()
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .collect_vec();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert_ne!(start.0, usize::MAX);
 | 
				
			||||||
 | 
					    assert_ne!(target.0, usize::MAX);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let rows = map.len();
 | 
				
			||||||
 | 
					    let cols;
 | 
				
			||||||
 | 
					    if let itertools::MinMaxResult::MinMax(min, max) = map.iter().map(|r| r.len()).minmax() {
 | 
				
			||||||
 | 
					        cols = min;
 | 
				
			||||||
 | 
					        assert_eq!(min, max);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        panic!("<2 rows?");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Heightmap {
 | 
				
			||||||
 | 
					        map,
 | 
				
			||||||
 | 
					        cols,
 | 
				
			||||||
 | 
					        rows,
 | 
				
			||||||
 | 
					        start,
 | 
				
			||||||
 | 
					        target,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn path_steps(map: &Heightmap) -> Option<usize> {
 | 
				
			||||||
 | 
					    let mut dist = vec![vec![usize::MAX; map.cols]; map.rows];
 | 
				
			||||||
 | 
					    dist[map.start.0][map.start.1] = 0;
 | 
				
			||||||
 | 
					    let mut next = VecDeque::new();
 | 
				
			||||||
 | 
					    next.push_back(map.start);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let moves: Vec<(isize, isize)> = vec![(1, 0), (-1, 0), (0, 1), (0, -1)];
 | 
				
			||||||
 | 
					    while let Some(coord) = next.pop_front() {
 | 
				
			||||||
 | 
					        if coord == map.target {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        let curr_height = map.map[coord.0][coord.1];
 | 
				
			||||||
 | 
					        let curr_dist = dist[coord.0][coord.1];
 | 
				
			||||||
 | 
					        for move_ in &moves {
 | 
				
			||||||
 | 
					            let y = (coord.0 as isize) + move_.0;
 | 
				
			||||||
 | 
					            if y < 0 || y >= map.rows as isize {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            let x = (coord.1 as isize) + move_.1;
 | 
				
			||||||
 | 
					            if x < 0 || x >= map.cols as isize {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            let y = y as usize;
 | 
				
			||||||
 | 
					            let x = x as usize;
 | 
				
			||||||
 | 
					            if map.map[y][x] <= curr_height + 1 && dist[y][x] > curr_dist + 1 {
 | 
				
			||||||
 | 
					                dist[y][x] = curr_dist + 1;
 | 
				
			||||||
 | 
					                next.push_back((y, x));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let d = dist[map.target.0][map.target.1];
 | 
				
			||||||
 | 
					    if d < usize::MAX {
 | 
				
			||||||
 | 
					        Some(d)
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        None
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
pub mod day1;
 | 
					pub mod day1;
 | 
				
			||||||
pub mod day10;
 | 
					pub mod day10;
 | 
				
			||||||
pub mod day11;
 | 
					pub mod day11;
 | 
				
			||||||
 | 
					pub mod day12;
 | 
				
			||||||
pub mod day2;
 | 
					pub mod day2;
 | 
				
			||||||
pub mod day3;
 | 
					pub mod day3;
 | 
				
			||||||
pub mod day4;
 | 
					pub mod day4;
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user