mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Reduce runtime by 90% by eliminating hashsets
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::HashSet;
|
|
||||||
|
|
||||||
use crate::common::Grid;
|
use crate::common::Grid;
|
||||||
use crate::common::IndexSet;
|
use crate::common::IndexSet;
|
||||||
@@ -121,7 +120,7 @@ fn longest_path(
|
|||||||
pos: usize,
|
pos: usize,
|
||||||
travelled: u32,
|
travelled: u32,
|
||||||
graph: &[Vec<(Slope, usize, u32)>],
|
graph: &[Vec<(Slope, usize, u32)>],
|
||||||
visited: &mut HashSet<usize>,
|
visited: u64,
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
if pos == 1 {
|
if pos == 1 {
|
||||||
return travelled;
|
return travelled;
|
||||||
@@ -130,9 +129,12 @@ fn longest_path(
|
|||||||
let mut best = 0;
|
let mut best = 0;
|
||||||
|
|
||||||
for &(slope, other, dist) in &graph[pos] {
|
for &(slope, other, dist) in &graph[pos] {
|
||||||
if !matches!(slope, Slope::Up) && visited.insert(other) {
|
let index = 1u64 << other;
|
||||||
best = Ord::max(best, longest_path(other, travelled + dist, graph, visited));
|
if !matches!(slope, Slope::Up) && (visited & index) == 0 {
|
||||||
visited.remove(&other);
|
best = Ord::max(
|
||||||
|
best,
|
||||||
|
longest_path(other, travelled + dist, graph, visited | index),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,14 +144,14 @@ fn longest_path(
|
|||||||
pub fn part1(input: &[u8]) -> anyhow::Result<String> {
|
pub fn part1(input: &[u8]) -> anyhow::Result<String> {
|
||||||
let graph = simplify_graph(input)?;
|
let graph = simplify_graph(input)?;
|
||||||
|
|
||||||
Ok(longest_path(0, 0, &graph, &mut HashSet::new()).to_string())
|
Ok(longest_path(0, 0, &graph, 0).to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn longer_longest_path(
|
fn longer_longest_path(
|
||||||
pos: usize,
|
pos: usize,
|
||||||
travelled: u32,
|
travelled: u32,
|
||||||
graph: &[Vec<(Slope, usize, u32)>],
|
graph: &[Vec<(Slope, usize, u32)>],
|
||||||
visited: &mut HashSet<usize>,
|
visited: u64,
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
if pos == 1 {
|
if pos == 1 {
|
||||||
return travelled;
|
return travelled;
|
||||||
@@ -158,12 +160,12 @@ fn longer_longest_path(
|
|||||||
let mut best = 0;
|
let mut best = 0;
|
||||||
|
|
||||||
for &(_, other, dist) in &graph[pos] {
|
for &(_, other, dist) in &graph[pos] {
|
||||||
if visited.insert(other) {
|
let index = 1u64 << other;
|
||||||
|
if (visited & index) == 0 {
|
||||||
best = Ord::max(
|
best = Ord::max(
|
||||||
best,
|
best,
|
||||||
longer_longest_path(other, travelled + dist, graph, visited),
|
longer_longest_path(other, travelled + dist, graph, visited | index),
|
||||||
);
|
);
|
||||||
visited.remove(&other);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +175,7 @@ fn longer_longest_path(
|
|||||||
pub fn part2(input: &[u8]) -> anyhow::Result<String> {
|
pub fn part2(input: &[u8]) -> anyhow::Result<String> {
|
||||||
let graph = simplify_graph(input)?;
|
let graph = simplify_graph(input)?;
|
||||||
|
|
||||||
Ok(longer_longest_path(0, 0, &graph, &mut HashSet::new()).to_string())
|
Ok(longer_longest_path(0, 0, &graph, 0).to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
Reference in New Issue
Block a user