diff --git a/workspaces/adventure-pack/goodies/python3/src/traverse_inorder/__init__.py b/workspaces/adventure-pack/goodies/python3/src/traverse_inorder/__init__.py new file mode 100644 index 00000000..c2208d2f --- /dev/null +++ b/workspaces/adventure-pack/goodies/python3/src/traverse_inorder/__init__.py @@ -0,0 +1,31 @@ +from typing import Generator, Optional + + +class TreeNode: + def __init__( + self, + val: int = 0, + left: Optional["TreeNode"] = None, + right: Optional["TreeNode"] = None, + ): + self.val = val + self.left = left + self.right = right + + +def traverse_inorder( + root: Optional[TreeNode], +) -> Generator[TreeNode, None, None]: + stack = [(root, False)] + while stack: + node, did_traverse_left_child = stack.pop() + if not node: + continue + + if did_traverse_left_child: + yield node + continue + + stack.append((node.right, False)) + stack.append((node, True)) + stack.append((node.left, False)) diff --git a/workspaces/adventure-pack/goodies/python3/src/traverse_inorder/goody.json b/workspaces/adventure-pack/goodies/python3/src/traverse_inorder/goody.json new file mode 100644 index 00000000..83a2a846 --- /dev/null +++ b/workspaces/adventure-pack/goodies/python3/src/traverse_inorder/goody.json @@ -0,0 +1,3 @@ +{ + "name": "traverse_inorder" +} diff --git a/workspaces/adventure-pack/goodies/python3/src/traverse_inorder/test.py b/workspaces/adventure-pack/goodies/python3/src/traverse_inorder/test.py new file mode 100644 index 00000000..61318c3a --- /dev/null +++ b/workspaces/adventure-pack/goodies/python3/src/traverse_inorder/test.py @@ -0,0 +1,82 @@ +from . import * + + +def test_empty_tree() -> None: + assert list(traverse_inorder(None)) == [] + + +def test_root_only() -> None: + root = TreeNode(10) + assert [node.val for node in traverse_inorder(root)] == [10] + + +def test_left_child_only() -> None: + root = TreeNode(10) + root.left = TreeNode(4) + assert [node.val for node in traverse_inorder(root)] == [4, 10] + + +def test_right_child_only() -> None: + root = TreeNode(10) + root.right = TreeNode(6) + assert [node.val for node in traverse_inorder(root)] == [10, 6] + + +def test_unbalanced_tree() -> None: + root = TreeNode(2) + root.left = TreeNode(4) + root.right = TreeNode(5) + root.left.left = TreeNode(7) + root.left.right = TreeNode(8) + root.left.left.left = TreeNode(10) + + assert [node.val for node in traverse_inorder(root)] == [ + 10, + 7, + 4, + 8, + 2, + 5, + ] + + +def test_large_tree() -> None: + root = TreeNode(1) + root.left = TreeNode(2) + root.right = TreeNode(3) + root.left.left = TreeNode(4) + root.left.right = TreeNode(5) + root.right.left = TreeNode(6) + root.right.right = TreeNode(7) + root.left.left.left = TreeNode(8) + root.left.left.right = TreeNode(9) + root.left.right.left = TreeNode(10) + root.left.right.right = TreeNode(11) + + assert [node.val for node in traverse_inorder(root)] == [ + 8, + 4, + 9, + 2, + 10, + 5, + 11, + 1, + 6, + 3, + 7, + ] + + +# TODO: delete test case once types are enforced for python goodies +def test_traverse_generator() -> None: + root = TreeNode(1) + root.left = TreeNode(2) + root.right = TreeNode(3) + root.left.left = TreeNode(4) + + traverse = traverse_inorder(root) + assert next(traverse).val == 4 + assert next(traverse).val == 2 + assert next(traverse).val == 1 + assert next(traverse).val == 3 diff --git a/workspaces/adventure-pack/goodies/python3/src/traverse_postorder/__init__.py b/workspaces/adventure-pack/goodies/python3/src/traverse_postorder/__init__.py index df2a821e..4d8c88e3 100644 --- a/workspaces/adventure-pack/goodies/python3/src/traverse_postorder/__init__.py +++ b/workspaces/adventure-pack/goodies/python3/src/traverse_postorder/__init__.py @@ -16,15 +16,16 @@ def __init__( def traverse_postorder( root: Optional[TreeNode], ) -> Generator[TreeNode, None, None]: - stack = [(root, False)] if root else [] + stack = [(root, False)] while stack: node, did_traverse_children = stack.pop() + if not node: + continue + if did_traverse_children: yield node continue stack.append((node, True)) - if node.right: - stack.append((node.right, False)) - if node.left: - stack.append((node.left, False)) + stack.append((node.right, False)) + stack.append((node.left, False)) diff --git a/workspaces/adventure-pack/goodies/python3/src/traverse_preorder/__init__.py b/workspaces/adventure-pack/goodies/python3/src/traverse_preorder/__init__.py index 13e9f9c4..403babfa 100644 --- a/workspaces/adventure-pack/goodies/python3/src/traverse_preorder/__init__.py +++ b/workspaces/adventure-pack/goodies/python3/src/traverse_preorder/__init__.py @@ -16,12 +16,13 @@ def __init__( def traverse_preorder( root: Optional[TreeNode], ) -> Generator[TreeNode, None, None]: - stack = [root] if root else [] + stack = [root] while stack: node = stack.pop() + if not node: + continue + yield node - if node.right: - stack.append(node.right) - if node.left: - stack.append(node.left) + stack.append(node.right) + stack.append(node.left) diff --git a/workspaces/adventure-pack/src/app/__tests__/__snapshots__/equip-test.ts.snap b/workspaces/adventure-pack/src/app/__tests__/__snapshots__/equip-test.ts.snap index 69cd9f99..a0bdda2e 100644 --- a/workspaces/adventure-pack/src/app/__tests__/__snapshots__/equip-test.ts.snap +++ b/workspaces/adventure-pack/src/app/__tests__/__snapshots__/equip-test.ts.snap @@ -2341,6 +2341,46 @@ def is_palindrome(sequence: list | str) -> bool: ########################### END ADVENTURE PACK CODE ############################" `; +exports[`App can equip single goody: Python 3 traverse_inorder 1`] = ` +"########################## BEGIN ADVENTURE PACK CODE ########################### +# Adventure Pack commit fake-commit-hash +# Running at: https://example.com/ + +from typing import Generator, Optional + + +class TreeNode: + def __init__( + self, + val: int = 0, + left: Optional["TreeNode"] = None, + right: Optional["TreeNode"] = None, + ): + self.val = val + self.left = left + self.right = right + + +def traverse_inorder( + root: Optional[TreeNode], +) -> Generator[TreeNode, None, None]: + stack = [(root, False)] + while stack: + node, did_traverse_left_child = stack.pop() + if not node: + continue + + if did_traverse_left_child: + yield node + continue + + stack.append((node.right, False)) + stack.append((node, True)) + stack.append((node.left, False)) + +########################### END ADVENTURE PACK CODE ############################" +`; + exports[`App can equip single goody: Python 3 traverse_postorder 1`] = ` "########################## BEGIN ADVENTURE PACK CODE ########################### # Adventure Pack commit fake-commit-hash @@ -2364,18 +2404,19 @@ class TreeNode: def traverse_postorder( root: Optional[TreeNode], ) -> Generator[TreeNode, None, None]: - stack = [(root, False)] if root else [] + stack = [(root, False)] while stack: node, did_traverse_children = stack.pop() + if not node: + continue + if did_traverse_children: yield node continue stack.append((node, True)) - if node.right: - stack.append((node.right, False)) - if node.left: - stack.append((node.left, False)) + stack.append((node.right, False)) + stack.append((node.left, False)) ########################### END ADVENTURE PACK CODE ############################" `; @@ -2403,15 +2444,16 @@ class TreeNode: def traverse_preorder( root: Optional[TreeNode], ) -> Generator[TreeNode, None, None]: - stack = [root] if root else [] + stack = [root] while stack: node = stack.pop() + if not node: + continue + yield node - if node.right: - stack.append(node.right) - if node.left: - stack.append(node.left) + stack.append(node.right) + stack.append(node.left) ########################### END ADVENTURE PACK CODE ############################" `; diff --git a/workspaces/adventure-pack/src/app/__tests__/__snapshots__/render-test.ts.snap b/workspaces/adventure-pack/src/app/__tests__/__snapshots__/render-test.ts.snap index 6f98c445..72602abb 100644 --- a/workspaces/adventure-pack/src/app/__tests__/__snapshots__/render-test.ts.snap +++ b/workspaces/adventure-pack/src/app/__tests__/__snapshots__/render-test.ts.snap @@ -1357,6 +1357,40 @@ exports[`App can render goody: Python 3 is_palindrome 1`] = ` return True" `; +exports[`App can render goody: Python 3 traverse_inorder 1`] = ` +"from typing import Generator, Optional + + +class TreeNode: + def __init__( + self, + val: int = 0, + left: Optional["TreeNode"] = None, + right: Optional["TreeNode"] = None, + ): + self.val = val + self.left = left + self.right = right + + +def traverse_inorder( + root: Optional[TreeNode], +) -> Generator[TreeNode, None, None]: + stack = [(root, False)] + while stack: + node, did_traverse_left_child = stack.pop() + if not node: + continue + + if did_traverse_left_child: + yield node + continue + + stack.append((node.right, False)) + stack.append((node, True)) + stack.append((node.left, False))" +`; + exports[`App can render goody: Python 3 traverse_postorder 1`] = ` "from typing import Generator, Optional @@ -1376,18 +1410,19 @@ class TreeNode: def traverse_postorder( root: Optional[TreeNode], ) -> Generator[TreeNode, None, None]: - stack = [(root, False)] if root else [] + stack = [(root, False)] while stack: node, did_traverse_children = stack.pop() + if not node: + continue + if did_traverse_children: yield node continue stack.append((node, True)) - if node.right: - stack.append((node.right, False)) - if node.left: - stack.append((node.left, False))" + stack.append((node.right, False)) + stack.append((node.left, False))" `; exports[`App can render goody: Python 3 traverse_preorder 1`] = ` @@ -1409,15 +1444,16 @@ class TreeNode: def traverse_preorder( root: Optional[TreeNode], ) -> Generator[TreeNode, None, None]: - stack = [root] if root else [] + stack = [root] while stack: node = stack.pop() + if not node: + continue + yield node - if node.right: - stack.append(node.right) - if node.left: - stack.append(node.left)" + stack.append(node.right) + stack.append(node.left)" `; exports[`App can render goody: TypeScript Array.prototype.slidingWindows 1`] = `