Finish day 12
parent
e7f95fc243
commit
81bf01201a
60
src/main.rs
60
src/main.rs
|
@ -1,4 +1,4 @@
|
|||
use std::collections::{HashMap, HashSet};
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::fmt::Debug;
|
||||
use std::fs;
|
||||
use std::ops::{Range, RangeInclusive};
|
||||
|
@ -279,11 +279,12 @@ solutions! {
|
|||
// day 12 part 1
|
||||
|input| {
|
||||
let map = Map::from_string(input);
|
||||
map.navigate().into()
|
||||
map.navigate(map.start).unwrap().into()
|
||||
},
|
||||
// day 12 part 1
|
||||
|input| {
|
||||
todo!()
|
||||
let map = Map::from_string(input);
|
||||
map.best_navigate().into()
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -296,27 +297,40 @@ struct Map {
|
|||
}
|
||||
|
||||
impl Map {
|
||||
fn navigate(self) -> u64 {
|
||||
// this is fuckin buggy
|
||||
let (mut x, mut y) = self.start;
|
||||
let mut last = (x, y);
|
||||
let mut prior = (x, y);
|
||||
let mut steps = 0;
|
||||
while (x, y) != self.end {
|
||||
let level = self.map[x][y];
|
||||
print!("moving from ({x},{y}) to ");
|
||||
prior = last;
|
||||
last = (x, y);
|
||||
(x, y, _) = self
|
||||
.neighbors(x, y)
|
||||
.filter(|(_, _, neighbor)| (level..=level + 1).contains(neighbor))
|
||||
.filter(|(nx, ny, _)| (*nx, *ny) != prior)
|
||||
.max_by_key(|(_, _, neighbor)| *neighbor)
|
||||
.unwrap();
|
||||
println!("({x},{y})");
|
||||
steps += 1;
|
||||
fn best_navigate(self) -> u64 {
|
||||
self.map
|
||||
.iter()
|
||||
.enumerate()
|
||||
.flat_map(|(x, row)| {
|
||||
row.iter()
|
||||
.enumerate()
|
||||
.map(move |(y, level)| (x, y, *level))
|
||||
.filter_map(|(x, y, level)| if level == 0 { Some((x, y)) } else { None })
|
||||
})
|
||||
.flat_map(|start| self.navigate(start))
|
||||
.min()
|
||||
.unwrap()
|
||||
}
|
||||
steps
|
||||
|
||||
fn navigate(&self, start: (usize, usize)) -> Option<u64> {
|
||||
let mut q = VecDeque::new();
|
||||
let mut visited = HashSet::new();
|
||||
visited.insert(start);
|
||||
q.push_back((start, 0));
|
||||
while !q.is_empty() {
|
||||
let ((x, y), steps) = q.pop_front().unwrap();
|
||||
let level = self.map[x][y];
|
||||
if (x, y) == self.end {
|
||||
return Some(steps);
|
||||
}
|
||||
for (nx, ny, nlevel) in self.neighbors(x, y) {
|
||||
if !visited.contains(&(nx, ny)) && nlevel <= level + 1 {
|
||||
visited.insert((nx, ny));
|
||||
q.push_back(((nx, ny), steps + 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn neighbors(&self, x: usize, y: usize) -> impl Iterator<Item = (usize, usize, isize)> {
|
||||
|
|
Loading…
Reference in New Issue