diff --git a/python_experiments/depth_first_search/depth_first_search.py b/python_experiments/depth_first_search/depth_first_search.py index d6804ae..a3d7587 100755 --- a/python_experiments/depth_first_search/depth_first_search.py +++ b/python_experiments/depth_first_search/depth_first_search.py @@ -21,11 +21,15 @@ def main(): activity_tree.activities[9] = Activity(id=9, parent=8, text="I") activity_tree.activities[10] = Activity(id=10, parent=9, text="J") - match_iter = MatchIter(activity_tree, lambda act: act.id in (2, 5, 10)) + match_iter = MatchIter( + activity_tree, + lambda act: act.id in (2, 5, 10), + lambda act: act.id in (4,), + ) while (depth_and_node := match_iter.get_next()) is not None: - depth, matched, node = depth_and_node - print("\t".join((str(depth), str(matched), node.text))) + depth, matched, transparent, node = depth_and_node + print("\t".join((str(depth), str(matched), str(transparent), node.text))) # while True: # print("\n\n\nvvvvvvvvvv\n\n") @@ -56,21 +60,27 @@ class MatchIter: activity_tree: ActivityTree stack: deque[StackEntry] is_match: Callable[[Activity], bool] + is_transparent: Callable[[Activity], bool] def __init__( - self, activity_tree: ActivityTree, is_match: Callable[[Activity], bool] + self, + activity_tree: ActivityTree, + is_match: Callable[[Activity], bool], + is_transparent: Callable[[Activity], bool], ) -> None: self.activity_tree = activity_tree self.stack = deque([StackEntry(0)]) self.is_match = is_match + self.is_transparent = is_transparent - def get_next(self) -> tuple[int, bool, Activity] | None: + def get_next(self) -> tuple[int, bool, bool, Activity] | None: if (next_announce := self.get_next_announce()) is not None: next_announce_depth, next_announce_entry = next_announce next_announce_entry.announced = True return ( next_announce_depth, next_announce_entry.matched, + next_announce_entry.transparent, self.activity_tree.activities[next_announce_entry.node_id], ) @@ -91,6 +101,7 @@ class MatchIter: parent.should_announce = True stack_entry.visited = True + stack_entry.transparent = self.is_transparent(node) children = [ c for c in self.activity_tree.activities.values() if c.parent == node.id @@ -109,6 +120,7 @@ class MatchIter: return ( next_announce_depth, next_announce_entry.matched, + next_announce_entry.transparent, self.activity_tree.activities[next_announce_entry.node_id], ) @@ -121,7 +133,13 @@ class MatchIter: def get_next_announce(self) -> tuple[int, StackEntry] | None: for entry in self.stack: if entry.should_announce and not entry.announced: - depth = len(list(self.walk_up_stack(entry))) + depth = len( + list( + entry + for entry in self.walk_up_stack(entry) + if not entry.transparent + ) + ) return (depth, entry) return None @@ -146,10 +164,11 @@ class StackEntry: should_announce: bool = False visited: bool = False matched: bool = False + transparent: bool = False def text(self, activity_tree: ActivityTree) -> str: node = activity_tree.activities[self.node_id] - return f"{node.text}\t{"annced" if self.announced else "-"}\t{"should" if self.should_announce else "-"}\t{"visited" if self.visited else "-"}\t{"matched" if self.matched else "-"}" + return f"{node.text}\t{"annced" if self.announced else "-"}\t{"should" if self.should_announce else "-"}\t{"visited" if self.visited else "-"}\t{"matched" if self.matched else "-"}\t{"trans" if self.transparent else "-"}" if __name__ == "__main__":