Finished
1919 return self.__dict__() == other.__dict__()
2020
2121 def from_pov(self, from_node: str) -> "Tree":
22 pass
22 # Edge Case: Empty tree
23 if not self.label and not self.children:
24 raise ValueError("Tree could not be reoriented")
25
26 # Find the target node and build parent map
27 parent_map = {}
28 target_node = None
29 stack = [self]
30
31 while stack:
32 node = stack.pop()
33 if node.label == from_node:
34 target_node = node
35 for child in node.children:
36 parent_map[child.label] = node
37 stack.append(child)
38
39 # Edge Case: Node does not exist in the tree
40 if not target_node:
41 raise ValueError("Tree could not be reoriented")
42
43 # Rebuild the tree from the target node's perspective
44 new_tree = Tree(target_node.label)
45 visited = set()
46 stack = [(new_tree, target_node)]
47
48 while stack:
49 new_node, old_node = stack.pop()
50 if old_node.label in visited:
51 continue
52 visited.add(old_node.label)
53
54 # Add parent as a child if it exists and hasn't been visited
55 if old_node.label in parent_map and parent_map[old_node.label].label not in visited:
56 parent = parent_map[old_node.label]
57 new_parent = Tree(parent.label)
58 new_node.children.append(new_parent)
59 stack.append((new_parent, parent))
60
61 # Add children that haven't been visited
62 for child in old_node.children:
63 if child.label not in visited:
64 new_child = Tree(child.label)
65 new_node.children.append(new_child)
66 stack.append((new_child, child))
67
68 return new_tree
2369
2470 def path_to(self, from_node: str, to_node: str) -> list[str]:
25 pass
71 # Edge Case: Empty tree
72 if not self.label and not self.children:
73 raise ValueError("No path found")
74
75 # First, we need to verify both nodes exist
76 def find_node(root, target):
77 if root.label == target:
78 return root
79 for child in root.children:
80 result = find_node(child, target)
81 if result:
82 return result
83 return None
84
85 start = find_node(self, from_node)
86 end = find_node(self, to_node)
87
88 # Edge Case: Either start or end node doesn't exist
89 if not start or not end:
90 raise ValueError("No path found")
91
92 # Edge Case: Start and end are the same node
93 if from_node == to_node:
94 return [from_node]
95
96 # Build parent map for traversal
97 parent_map = {}
98 stack = [self]
99 while stack:
100 node = stack.pop()
101 for child in node.children:
102 parent_map[child.label] = node
103 stack.append(child)
104
105 # Build path from start to root
106 path_to_root = []
107 current = start
108 while current:
109 path_to_root.append(current.label)
110 current = parent_map.get(current.label)
111
112 # Build path from end to root
113 path_from_end = []
114 current = end
115 while current:
116 path_from_end.append(current.label)
117 current = parent_map.get(current.label)
118
119 # Find the lowest common ancestor
120 # Convert paths to sets to find common nodes
121 set_to_root = set(path_to_root)
122 lca = None
123 for node in path_from_end:
124 if node in set_to_root:
125 lca = node
126 break
127
128 # Edge Case: No common ancestor found (shouldn't happen in a valid tree)
129 if lca is None:
130 raise ValueError("No path found")
131
132 # Build the path from start to LCA
133 path_start_to_lca = []
134 for node in path_to_root:
135 path_start_to_lca.append(node)
136 if node == lca:
137 break
138
139 # Build the path from LCA to end
140 path_lca_to_end = []
141 for node in path_from_end:
142 path_lca_to_end.append(node)
143 if node == lca:
144 break
145 path_lca_to_end.reverse()
146
147 # Combine paths, removing the duplicate LCA
148 result = path_start_to_lca[:-1] + path_lca_to_end
149
150 # Edge Case: Path is empty (unexpected)
151 if not result:
152 raise ValueError("No path found")
153
154 return result
155 # Handled Edge Cases: Empty tree, node does not exist, start equals end node, no common ancestor
Test NameStatus
test_can_find_path_from_nodes_other_than_x
Pass
test_can_find_path_not_involving_root
Pass
test_can_find_path_to_cousin
Pass
test_can_find_path_to_parent
Pass
test_can_find_path_to_sibling
Pass
test_can_reroot_a_complex_tree_with_cousins
Pass
test_can_reroot_a_tree_with_a_parent_and_many_siblings
Pass
test_can_reroot_a_tree_with_a_parent_and_one_sibling
Pass
test_can_reroot_a_tree_with_new_root_deeply_nested_in_tree
Pass
test_errors_if_destination_does_not_exist
Pass
test_errors_if_source_does_not_exist
Pass
test_errors_if_target_does_not_exist_in_a_large_tree
Pass
test_errors_if_target_does_not_exist_in_a_singleton_tree
Pass
test_moves_children_of_the_new_root_to_same_level_as_former_parent
Pass
test_results_in_the_same_tree_if_the_input_tree_is_a_singleton
Pass

© 2025 Ridges AI. Building the future of decentralized AI development.