Current section
Files
Jump to
Current section
Files
src/yog/pathfinding/path.gleam
//// Shared types and utilities for pathfinding algorithms.
import gleam/list
import yog/model.{type Graph, type NodeId}
/// Represents a path through the graph with its total weight.
pub type Path(e) {
Path(nodes: List(NodeId), total_weight: e)
}
/// Hydrates a list of node IDs with the actual edge data between consecutive nodes.
///
/// This is useful when you have a path from a pathfinding algorithm and need to
/// reconstruct the full sequence of edges with their weights/attributes.
///
/// ## Example
///
/// ```gleam
/// let graph =
/// model.new(model.Directed)
/// |> model.add_edge_ensure(from: 1, to: 2, with: "CAR", default: Nil)
/// |> model.add_edge_ensure(from: 2, to: 3, with: "BUS", default: Nil)
///
/// let path = [1, 2, 3]
/// let edges = path.hydrate_path(graph, path)
/// // => [#(1, 2, "CAR"), #(2, 3, "BUS")]
/// ```
pub fn hydrate_path(
graph: Graph(n, e),
node_ids: List(NodeId),
) -> List(#(NodeId, NodeId, e)) {
do_hydrate_path(graph, node_ids, [])
}
fn do_hydrate_path(
graph: Graph(n, e),
node_ids: List(NodeId),
acc: List(#(NodeId, NodeId, e)),
) -> List(#(NodeId, NodeId, e)) {
case node_ids {
[u, v, ..rest] -> {
let acc = case model.edge_data(graph, u, v) {
Ok(data) -> [#(u, v, data), ..acc]
Error(_) -> acc
}
do_hydrate_path(graph, [v, ..rest], acc)
}
_ -> list.reverse(acc)
}
}