optimize p2
This commit is contained in:
parent
2de9cca374
commit
515b47714d
|
@ -1,5 +1,7 @@
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use aoc2022::{
|
use aoc2022::{
|
||||||
boilerplate,
|
boilerplate,
|
||||||
common::*,
|
common::*,
|
||||||
|
@ -35,36 +37,33 @@ fn parse_input(raw: &str) -> Parsed {
|
||||||
(start, end, grid)
|
(start, end, grid)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is like… O(n³) or something for grid size n :tehe:
|
|
||||||
fn part1((start, end, grid): &Parsed) -> usize {
|
fn part1((start, end, grid): &Parsed) -> usize {
|
||||||
let xbounds = 0..grid.len();
|
let xbounds = 0..grid.len();
|
||||||
let ybounds = 0..grid.fields[0].len();
|
let ybounds = 0..grid.fields[0].len();
|
||||||
let mut distances = VecGrid { fields: vec![vec![usize::MAX; ybounds.end]; xbounds.end] };
|
let mut distances = VecGrid { fields: vec![vec![usize::MAX; ybounds.end]; xbounds.end] };
|
||||||
|
let mut visited = VecGrid { fields: vec![vec![false; ybounds.end]; xbounds.end] };
|
||||||
|
let mut points_to_consider = HashSet::from([*start]);
|
||||||
distances[*start] = 0;
|
distances[*start] = 0;
|
||||||
let mut curr = *start;
|
let mut curr = *start;
|
||||||
loop {
|
loop {
|
||||||
if &curr == end {
|
if &curr == end {
|
||||||
return distances[curr];
|
return distances[curr];
|
||||||
}
|
}
|
||||||
|
points_to_consider.remove(&curr);
|
||||||
for n in curr
|
for n in curr
|
||||||
.neighbors_no_diagonals()
|
.neighbors_no_diagonals()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|&PositionND([x, y])| xbounds.contains(&(x as usize)) && ybounds.contains(&(y as usize)))
|
.filter(|&PositionND([x, y])| xbounds.contains(&(x as usize)) && ybounds.contains(&(y as usize)))
|
||||||
{
|
{
|
||||||
|
if !visited[n] {
|
||||||
if grid[curr] >= grid[n] || grid[n] - grid[curr] == 1 {
|
if grid[curr] >= grid[n] || grid[n] - grid[curr] == 1 {
|
||||||
distances[n] = distances[n].min(distances[curr] + 1);
|
distances[n] = distances[n].min(distances[curr] + 1);
|
||||||
}
|
}
|
||||||
|
points_to_consider.insert(n);
|
||||||
}
|
}
|
||||||
distances[curr] = usize::MAX;
|
}
|
||||||
let min = distances.fields.iter().flatten().min().unwrap();
|
visited[curr] = true;
|
||||||
curr = distances
|
curr = *points_to_consider.iter().min_by_key(|&&p| distances[p]).unwrap();
|
||||||
.fields
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.find_map(|(x, row)| {
|
|
||||||
row.iter().enumerate().find_map(|(y, e)| (e == min).then_some(y)).map(|y| PositionND([x as i64, y as i64]))
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,31 +71,29 @@ fn part2((_, end, grid): &Parsed) -> usize {
|
||||||
let xbounds = 0..grid.len();
|
let xbounds = 0..grid.len();
|
||||||
let ybounds = 0..grid.fields[0].len();
|
let ybounds = 0..grid.fields[0].len();
|
||||||
let mut distances = VecGrid { fields: vec![vec![usize::MAX; ybounds.end]; xbounds.end] };
|
let mut distances = VecGrid { fields: vec![vec![usize::MAX; ybounds.end]; xbounds.end] };
|
||||||
|
let mut visited = VecGrid { fields: vec![vec![false; ybounds.end]; xbounds.end] };
|
||||||
|
let mut points_to_consider = HashSet::from([*end]);
|
||||||
distances[*end] = 0;
|
distances[*end] = 0;
|
||||||
let mut curr = *end;
|
let mut curr = *end;
|
||||||
loop {
|
loop {
|
||||||
if grid[curr] == b'a' {
|
if grid[curr] == b'a' {
|
||||||
return distances[curr];
|
return distances[curr];
|
||||||
}
|
}
|
||||||
|
points_to_consider.remove(&curr);
|
||||||
for n in curr
|
for n in curr
|
||||||
.neighbors_no_diagonals()
|
.neighbors_no_diagonals()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|&PositionND([x, y])| xbounds.contains(&(x as usize)) && ybounds.contains(&(y as usize)))
|
.filter(|&PositionND([x, y])| xbounds.contains(&(x as usize)) && ybounds.contains(&(y as usize)))
|
||||||
{
|
{
|
||||||
|
if !visited[n] {
|
||||||
if grid[curr] <= grid[n] || grid[curr] - grid[n] == 1 {
|
if grid[curr] <= grid[n] || grid[curr] - grid[n] == 1 {
|
||||||
distances[n] = distances[n].min(distances[curr] + 1);
|
distances[n] = distances[n].min(distances[curr] + 1);
|
||||||
}
|
}
|
||||||
|
points_to_consider.insert(n);
|
||||||
}
|
}
|
||||||
distances[curr] = usize::MAX;
|
}
|
||||||
let min = distances.fields.iter().flatten().min().unwrap();
|
visited[curr] = true;
|
||||||
curr = distances
|
curr = *points_to_consider.iter().min_by_key(|&&p| distances[p]).unwrap();
|
||||||
.fields
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.find_map(|(x, row)| {
|
|
||||||
row.iter().enumerate().find_map(|(y, e)| (e == min).then_some(y)).map(|y| PositionND([x as i64, y as i64]))
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user