diff --git a/src/path_finding.rs b/src/path_finding.rs index 2ba9629..8392140 100644 --- a/src/path_finding.rs +++ b/src/path_finding.rs @@ -2,7 +2,13 @@ // because these kind of problems will often occurs in Advent of Code use crate::{debug, test}; -use std::{cell::RefCell, cmp::min, fmt::Debug, ops::Deref, rc::Rc}; +use std::{ + cell::RefCell, + cmp::min, + fmt::{Debug, Display}, + ops::Deref, + rc::Rc, +}; /// Custom types type Int = i32; @@ -59,14 +65,14 @@ impl Edge { } } -struct Graph { +struct Graph { visited_nodes: NodeRefs, unvisited_nodes: NodeRefs, edges: Edges, starting_node: NodeRef, } -impl Graph { +impl Graph { fn new(starting_state: T) -> Graph { let starting_node: NodeRef = Node::new_ref(starting_state, Some(0)); starting_node.borrow_mut().visited = true; @@ -88,6 +94,15 @@ impl Graph { self.edges.push(new_edge); } + /// Add all `Edges` to `self.edges` from new or existing `Nodes` with specified `states`` + fn add_edges(&mut self, edges: Vec<(T, T, Distance)>) { + edges + .into_iter() + .for_each(|(first_state, second_state, distance)| { + self.add_edge(first_state, second_state, distance) + }); + } + /// Insert a `Node` into `self.unvisited_nodes` if there is /// no `Node` with specified `state` in `self. /// unvisited_nodes` or `self.visited_nodes`, or do nothing @@ -218,13 +233,35 @@ impl Graph { } } - fn get_distance(&self, state: T) -> DistanceOption { - let node_ref_option: Option> = self.get_node_ref(state); + /// Return the distance of a Node in this Graph. + /// + /// Run `run_pathfinding_algorithm()` first. + /// + /// Will panic if there is no Node in this Graph with the specified state, + /// or if the Node has no distance. + fn get_distance(&self, state: T) -> Distance { + let node_ref_option: Option> = self.get_node_ref(state.clone()); match node_ref_option { - Some(node_ref) => node_ref.borrow().distance_option, - _ => None, + Some(node_ref) => node_ref.borrow().distance_option.unwrap(), + _ => panic!("No Node in Graph with state: {:?}.", state), } } + + /// Test the distance of a Node in this Graph. + /// + /// Run `run_pathfinding_algorithm()` first. + /// + /// Will panic if there is no Node in this Graph with the specified state, + /// or if the Node has no distance, or if the distance is incorrect. + fn test_distance(&self, state: T, expected: Distance) { + test!( + expected, + self.get_distance(state), + "Distance {} == {}", + state, + expected + ); + } } #[test] @@ -241,7 +278,7 @@ fn test_case_a() { ("f", "g", 5), ("g", "f", 2), ]; - edges.iter().for_each(|e| graph.add_edge(e.0, e.1, e.2)); + graph.add_edges(edges); graph.run_pathfinding_algorithm(); dbg!(&graph.unvisited_nodes); dbg!(&graph.visited_nodes); @@ -255,6 +292,6 @@ fn test_case_a() { ("g", 13), ]; distances.iter().for_each(|t| { - test!(t.1, graph.get_distance(t.0).unwrap(), "{} == {}", t.0, t.1); + graph.test_distance(t.0, t.1); }); }