harrison

Finished
11class Zipper:
2 # Tree is a dict with keys "value" (int), "left" (dict or None), "right" (dict or None)
2 """
3 A zipper for navigating and manipulating a binary tree.
4
5 A zipper contains a data structure and a pointer (focus) into that structure.
6 It supports moving through the tree and modifying it in a functional way.
7 """
8
9 def __init__(self, tree, breadcrumbs=None):
10 """
11 Initialize a Zipper.
12
13 Args:
14 tree: The current subtree (focus) as a dict with keys 'value', 'left', 'right'
15 breadcrumbs: A list of tuples tracking the path back to the root
16 """
17 self.tree = tree
18 self.breadcrumbs = breadcrumbs or []
19
320 @staticmethod
421 def from_tree(tree: dict) -> "Zipper":
5 pass
6
22 """
23 Create a zipper from a binary tree.
24
25 Args:
26 tree: A binary tree represented as a dict with keys 'value', 'left', 'right'
27
28 Returns:
29 A new Zipper instance focused on the root of the tree
30
31 Edge Case: Empty tree (None) is handled by creating an empty zipper
32 """
33 # Edge Case: Handle None tree
34 if tree is None:
35 return Zipper(None)
36 return Zipper(tree)
37
738 def value(self) -> int:
8 pass
9
39 """
40 Get the value of the focus node.
41
42 Returns:
43 The value of the current node
44
45 Edge Case: If the current tree is None, this would raise an error in a real implementation,
46 but based on the problem constraints, we assume the tree is valid when this method is called.
47 """
48 return self.tree["value"]
49
1050 def set_value(self, value: int) -> "Zipper":
11 pass
12
51 """
52 Set the value of the focus node.
53
54 Args:
55 value: The new value for the focus node
56
57 Returns:
58 A new Zipper with the updated value
59
60 Edge Case: If the current tree is None, creates a new node with the given value
61 """
62 # Edge Case: If current tree is None, create a new node
63 if self.tree is None:
64 new_tree = {"value": value, "left": None, "right": None}
65 else:
66 new_tree = {"value": value, "left": self.tree["left"], "right": self.tree["right"]}
67 return Zipper(new_tree, self.breadcrumbs)
68
1369 def left(self) -> "Zipper | None":
14 pass
15
70 """
71 Move the focus to the left child of the current node.
72
73 Returns:
74 A new Zipper focused on the left child, or None if there is no left child
75
76 Edge Case: If there's no left child or current tree is None, returns None
77 """
78 # Edge Case: Current tree is None
79 if self.tree is None:
80 return None
81
82 # Edge Case: No left child
83 if self.tree["left"] is None:
84 return None
85
86 # Create breadcrumb to remember how to reconstruct the parent
87 breadcrumb = {
88 "parent": {
89 "value": self.tree["value"],
90 "right": self.tree["right"]
91 },
92 "is_left": True
93 }
94
95 return Zipper(self.tree["left"], self.breadcrumbs + [breadcrumb])
96
1697 def set_left(self, tree: dict | None) -> "Zipper":
17 pass
18
98 """
99 Set the left child of the focus node.
100
101 Args:
102 tree: The new left subtree (or None to remove the left child)
103
104 Returns:
105 A new Zipper with the updated left child
106
107 Edge Case: If current tree is None, creates a new node with the given left subtree
108 """
109 # Edge Case: If current tree is None, create a new node
110 if self.tree is None:
111 new_tree = {"value": 0, "left": tree, "right": None} # Default value 0
112 else:
113 new_tree = {"value": self.tree["value"], "left": tree, "right": self.tree["right"]}
114 return Zipper(new_tree, self.breadcrumbs)
115
19116 def right(self) -> "Zipper | None":
20 pass
21
117 """
118 Move the focus to the right child of the current node.
119
120 Returns:
121 A new Zipper focused on the right child, or None if there is no right child
122
123 Edge Case: If there's no right child or current tree is None, returns None
124 """
125 # Edge Case: Current tree is None
126 if self.tree is None:
127 return None
128
129 # Edge Case: No right child
130 if self.tree["right"] is None:
131 return None
132
133 # Create breadcrumb to remember how to reconstruct the parent
134 breadcrumb = {
135 "parent": {
136 "value": self.tree["value"],
137 "left": self.tree["left"]
138 },
139 "is_left": False
140 }
141
142 return Zipper(self.tree["right"], self.breadcrumbs + [breadcrumb])
143
22144 def set_right(self, tree: dict | None) -> "Zipper":
23 pass
24
145 """
146 Set the right child of the focus node.
147
148 Args:
149 tree: The new right subtree (or None to remove the right child)
150
151 Returns:
152 A new Zipper with the updated right child
153
154 Edge Case: If current tree is None, creates a new node with the given right subtree
155 """
156 # Edge Case: If current tree is None, create a new node
157 if self.tree is None:
158 new_tree = {"value": 0, "left": None, "right": tree} # Default value 0
159 else:
160 new_tree = {"value": self.tree["value"], "left": self.tree["left"], "right": tree}
161 return Zipper(new_tree, self.breadcrumbs)
162
25163 def up(self) -> "Zipper | None":
26 pass
27
164 """
165 Move the focus to the parent of the current node.
166
167 Returns:
168 A new Zipper focused on the parent, or None if there is no parent (at root)
169
170 Edge Case: If there are no breadcrumbs (at root), returns None
171 """
172 # Edge Case: Already at root (no breadcrumbs)
173 if not self.breadcrumbs:
174 return None
175
176 # Get the last breadcrumb
177 last_breadcrumb = self.breadcrumbs[-1]
178 parent_info = last_breadcrumb["parent"]
179 is_left = last_breadcrumb["is_left"]
180
181 # Reconstruct the parent tree
182 if is_left:
183 # We were the left child
184 reconstructed_tree = {
185 "value": parent_info["value"],
186 "left": self.tree,
187 "right": parent_info["right"]
188 }
189 else:
190 # We were the right child
191 reconstructed_tree = {
192 "value": parent_info["value"],
193 "left": parent_info["left"],
194 "right": self.tree
195 }
196
197 return Zipper(reconstructed_tree, self.breadcrumbs[:-1])
198
28199 def to_tree(self) -> dict:
29 pass
200 """
201 Get the complete binary tree from the zipper.
202
203 Returns:
204 The complete binary tree as a dict
205
206 Edge Case: If the current focus is None, reconstructs the tree from breadcrumbs
207 """
208 # Start with the current tree
209 current = self.tree
210
211 # Work backwards through breadcrumbs to reconstruct the full tree
212 for breadcrumb in reversed(self.breadcrumbs):
213 parent_info = breadcrumb["parent"]
214 is_left = breadcrumb["is_left"]
215
216 if is_left:
217 # Current was the left child
218 current = {
219 "value": parent_info["value"],
220 "left": current,
221 "right": parent_info["right"]
222 }
223 else:
224 # Current was the right child
225 current = {
226 "value": parent_info["value"],
227 "left": parent_info["left"],
228 "right": current
229 }
230
231 return current
232
233 # Handled Edge Cases: Empty tree, None tree, no children, no parent, setting values on None nodes
Test NameStatus
test_data_is_retained
Pass
test_dead_end
Pass
test_different_paths_to_same_zipper
Pass
test_left_right_and_up
Pass
test_left_right_and_value
Pass
test_set_left_with_leaf
Pass
test_set_right_with_null
Pass
test_set_right_with_subtree
Pass
test_set_value
Pass
test_set_value_after_traversing_up
Pass
test_set_value_on_deep_focus
Pass
test_test_ability_to_descend_multiple_levels_and_return
Pass
test_traversing_up_from_top
Pass
test_tree_from_deep_focus
Pass

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