Skip to content

Commit

Permalink
Revert "attempt naive tracking of visited"
Browse files Browse the repository at this point in the history
This reverts commit fb0d7ad.
  • Loading branch information
brettporter committed Jan 4, 2024
1 parent fb0d7ad commit ab7d28d
Showing 1 changed file with 26 additions and 32 deletions.
58 changes: 26 additions & 32 deletions src/bin/23.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ impl Direction {
}
}

#[derive(Debug, Eq, Hash, PartialEq, Clone)]
#[derive(Debug, Eq, Hash, PartialEq, Clone, Copy)]
struct Node {
loc: (usize, usize),
visited: Vec<(usize, usize)>,
incoming_direction: Direction,
}

#[derive(Debug)]
Expand All @@ -48,18 +48,22 @@ fn traverse_grid(input: &str, slippery: bool) -> Option<i32> {
let (w, h) = (grid[0].len(), grid.len());
let start = Node {
loc: (1, 0),
visited: vec![],
incoming_direction: Direction::Down,
};
let dest = Node {
loc: (w - 2, h - 1),
incoming_direction: Direction::Down,
};
let dest = (w - 2, h - 1);

// TODO: too much copying of nodes instead of references?
let mut queue = VecDeque::new();
queue.push_back((start.clone(), Direction::Down));
queue.push_back((start, Direction::Down));

// TODO: ignore direction if slippery, as it is inherently directed

let mut nodes = FxHashSet::default();
nodes.insert(start);
nodes.insert(dest);

let mut edges = Vec::new(); // TODO: correct data structure?

Expand All @@ -75,14 +79,13 @@ fn traverse_grid(input: &str, slippery: bool) -> Option<i32> {
loop {
distance += 1;

if loc == dest {
let mut visited = junction.visited.clone();
visited.push(dest);
let nn = Node { loc, visited };
nodes.insert(nn.clone());
if loc == dest.loc {
edges.push(Edge {
from: junction,
to: nn,
to: Node {
loc,
incoming_direction,
},
distance,
});
break;
Expand Down Expand Up @@ -140,25 +143,20 @@ fn traverse_grid(input: &str, slippery: bool) -> Option<i32> {
} else {
// Reached a junction point
// if this node exists coming from the given incoming direction, add an edge and stop, otherwise add a node and push back all the points
if junction.visited.contains(&loc) {
break;
}

// TOOD: cleanup unecessary cloning

let mut visited = junction.visited.clone();
visited.push(loc);
let new_node = Node { loc, visited };
let new_node = Node {
loc,
incoming_direction,
};

if !nodes.contains(&new_node) {
nodes.insert(new_node);
for d in choices {
queue.push_back((new_node.clone(), d));
queue.push_back((new_node, d));
}
nodes.insert(new_node.clone());
}
edges.push(Edge {
from: junction,
to: new_node.clone(),
to: new_node,
distance,
});

Expand All @@ -175,10 +173,9 @@ fn traverse_grid(input: &str, slippery: bool) -> Option<i32> {
topo_sort(n, &edges, &mut visited, &mut stack);
}

// println!("Topological sort: {:#?}", stack);
println!("Topological sort: {:#?}", stack);

// TODO: is there a way to eliminate cycles in the graph or filter out here?
// TODO: only add the biggest ones...
// Find longest path
let mut max_distance = FxHashMap::default();
for n in stack {
Expand All @@ -188,13 +185,10 @@ fn traverse_grid(input: &str, slippery: bool) -> Option<i32> {
.filter(|e| e.to == n)
.map(|e| max_distance.get(&e.from).unwrap_or(&0) + e.distance)
.max();
max_distance.insert(n.clone(), d.unwrap_or(0));
max_distance.insert(n, d.unwrap_or(0));
}

max_distance
.into_iter()
.filter_map(|(n, d)| (n.loc == dest).then_some(d))
.max()
Some(*max_distance.get(&dest).unwrap())
}

fn topo_sort(
Expand All @@ -204,10 +198,10 @@ fn topo_sort(
stack: &mut VecDeque<Node>,
) {
if !visited.contains(&n) {
visited.insert(n.clone());
visited.insert(n);
// TODO: more efficient data structure?
for e in edges.iter().filter(|e| e.to == n) {
topo_sort(e.from.clone(), edges, visited, stack);
topo_sort(e.from, edges, visited, stack);
}
stack.push_back(n);
}
Expand Down

0 comments on commit ab7d28d

Please sign in to comment.