diff --git a/data_structures_and_algorithms/__pycache__/__init__.cpython-38.pyc b/data_structures_and_algorithms/__pycache__/__init__.cpython-38.pyc index 6cd44d6..10a9774 100644 Binary files a/data_structures_and_algorithms/__pycache__/__init__.cpython-38.pyc and b/data_structures_and_algorithms/__pycache__/__init__.cpython-38.pyc differ diff --git a/data_structures_and_algorithms/challenges/array_reverse/__pycache__/array_search.cpython-38.pyc b/data_structures_and_algorithms/challenges/array_reverse/__pycache__/array_search.cpython-38.pyc index 5d1378a..f7ea338 100644 Binary files a/data_structures_and_algorithms/challenges/array_reverse/__pycache__/array_search.cpython-38.pyc and b/data_structures_and_algorithms/challenges/array_reverse/__pycache__/array_search.cpython-38.pyc differ diff --git a/data_structures_and_algorithms/challenges/tree_intersection/hash.py b/data_structures_and_algorithms/challenges/tree_intersection/hash.py new file mode 100644 index 0000000..9da4246 --- /dev/null +++ b/data_structures_and_algorithms/challenges/tree_intersection/hash.py @@ -0,0 +1,214 @@ + +from typing import Any + +''' +A special kind of type is Any. A static type checker will treat every type as being compatible with Any and Any as being compatible with every type. + +This means that it is possible to perform any operation or method call on a value of type Any and assign it to any variable +''' + +class Node: + def __init__(self, key, val, _next): + self.key = key + self.val = val + self.next = _next + + def __str__(self): + return f'{self.val}' + + def __repr__(self): + return f'' + +class LinkedList(object): + def __init__(self, initial_data=None, tuple_data=None): + """This initializes the linked list object by creating a node for each value inputed. + ARGS: + Initial data can be either a list, or a single piece of data. + Tuple data can also be either a list, or a single piece of data. + """ + try: + self.head: Node = None + self._length: int = 0 + if initial_data is not None: + try: + for item in initial_data: + self.insert(item) + except: + self.insert(initial_data) + if tuple_data is not None: + try: + for item in tuple_data: + self.insert(item) + except: + self.insert(tuple_data) + except TypeError: + return TypeError + + def __str__(self): + return f'Head: {self.head} | Length: {self._length}' + + def __repr__(self): + return f'' + + def __len__(self): + return self._length + + def insert(self, key, val: Any) -> Any: + '''Creates a new node and appends it to the beginning of the list + This is done by re-stating which node is the head(the one youre appending) + then setting the previous head equal to the next value of the appended item + ''' + self.head = Node(key, val, self.head) + self._length += 1 + + def includes(self, key) -> bool: + '''Checks to see if a value is contained in the list by iterating through and + checking every node against the input value. If the value exists in the list + , the function will return true if it does not exist in the list, it will return false. + ''' + current = self.head + while current is not None: + if current.key is key: + return True + current = current.next + return False + + def append(self, val, key=None) -> bool: + '''Creates a new node and appends it at the end of the linked list + ''' + current = self.head + while current.next is not None: + current = current.next + current.next = Node(key, val, None) + return True + + def insert_before(self, val, target_val) -> bool: + '''Creates a new node and appends it before the target value + args: + new Node value, target Node value to insert before + returns: + True if the node was inserted + False if the target value is not in the SLL + ''' + current = self.head + while current.next.val is not target_val: + current = current.next + if current.next == None: + return False + current.next = Node(val, current.next) + return True + + def insert_after(self, val, target_val) -> bool: + '''Creates a new node and appends it after the target value + ''' + current = self.head + while current.val is not target_val: + current = current.next + if current == None: + return False + current.next = Node(val, current.next) + return True + + def find_k(self, k) ->bool: + '''Takes in an input value of K, which corresponds to that + many indexes from the end of the list. This function takes in the input, + and returns the value of the item at index of length - k. + ''' + if k < 0: + raise IndexError + tortoise = self.head + hare = self.head + for i in range(k): + if hare is not None: + hare = hare.next + else: + raise IndexError + while hare.next is not None: + hare = hare.next + tortoise = tortoise.next + return tortoise.val + +class HashTable: + """A class for a hash table.""" + entries_count = 0 + alphabet_size = 52 + + def __init__(self, size=8192): + self.table_size = size + self.hashtable = [None] * self.table_size + + def __repr__(self): + pass + + def _hash_key(self, key): + """Create a hash from a given key. + args: + key: a string to hash + returns: an integer corresponding to hashtable index + """ + hash_ = 0 + for i, c in enumerate(key): + hash_ += pow( + self.alphabet_size, len(key) - i - 1) * ord(c) + return hash_ % self.table_size + + def set(self, key, value): + """Add a key and value into the hash table. + args: + key: the key to store + value: the value to store + """ + if self.hashtable[self._hash_key(key)] is None: + self.hashtable[self._hash_key(key)] = LinkedList() + self.hashtable[self._hash_key(key)].insert(key, value) + self.entries_count += 1 + return True + if self.hashtable[self._hash_key(key)].includes(key): + raise TypeError + self.hashtable[self._hash_key(key)].insert(key, value) + self.entries_count += 1 + return False + + def get(self, key): + """Retrieve a value from the hash table by key. + args: + key: a string to find the value in the hash table + returns: the value stored with the key + """ + + linked_list = self.hashtable[self._hash_key(key)] + if linked_list is None: + raise TypeError + if linked_list.head is None: + raise TypeError + temp = linked_list.head + while linked_list: + if linked_list.head.key is key: + return linked_list.head.val + linked_list.head = linked_list.head.next + linked_list.head = temp + raise TypeError + + + def remove(self, key): + """Retrieve and remove a value from the hash table by key. + args: + key: a string to find the value in the hash table + returns: the value stored with the key + """ + ll = self.hashtable[self._hash_key(key)] + if ll is None: + raise TypeError + temp = ll.head + if ll.head.key is key: + temp = ll.head + ll.head = ll.head.next + return temp.val + while ll: + if ll.head.next.key is key: + temp = ll.head.next + ll.head.next = ll.head.next.next + return temp.val + if ll.head is None: + self.hashtable[self._hash_key(key)] = None + raise TypeError \ No newline at end of file diff --git a/data_structures_and_algorithms/challenges/tree_intersection/tree_intersection.py b/data_structures_and_algorithms/challenges/tree_intersection/tree_intersection.py new file mode 100644 index 0000000..e69de29 diff --git a/data_structures_and_algorithms/data_structures/graph/__pycache__/graph.cpython-38.pyc b/data_structures_and_algorithms/data_structures/graph/__pycache__/graph.cpython-38.pyc new file mode 100644 index 0000000..94a1a93 Binary files /dev/null and b/data_structures_and_algorithms/data_structures/graph/__pycache__/graph.cpython-38.pyc differ diff --git a/data_structures_and_algorithms/data_structures/graph/__pycache__/test_graph.cpython-38-pytest-6.1.2.pyc b/data_structures_and_algorithms/data_structures/graph/__pycache__/test_graph.cpython-38-pytest-6.1.2.pyc new file mode 100644 index 0000000..a1f38c0 Binary files /dev/null and b/data_structures_and_algorithms/data_structures/graph/__pycache__/test_graph.cpython-38-pytest-6.1.2.pyc differ diff --git a/data_structures_and_algorithms/data_structures/graph/graph.py b/data_structures_and_algorithms/data_structures/graph/graph.py new file mode 100644 index 0000000..4c8b656 --- /dev/null +++ b/data_structures_and_algorithms/data_structures/graph/graph.py @@ -0,0 +1,64 @@ +class Vertex: + def __init__(self, value): + self.value = value + self.neighbors = [] + +class Graph: + + def __init__(self): + self.vertices = [] + + def addVertex(self, value): + """ + AddVertex() + Adds a new vertex to the graph + Takes in the value of that vertex + Returns the added vertex + """ + + x = Vertex(value) + + self.vertices.append(x) + + return x + + def addEdge(self, v1, v2, weight): + """ + AddEdge() + Adds a new edge between two nodes in the graph + Include the ability to have a “weight” + Takes in the two nodes to be connected by the edge + Both nodes should already be in the Graph + """ + + + if v1 in self.vertices and v2 in self.vertices: + v1.neighbors.append( {v2, weight} ) + return + + return 'Please ensure both v1 and v2 exist in the graph' + + + #Infomation Retreival Functions + def getVertices(self): + """ + GetNodes() + Returns all of the nodes in the graph as a collection (set, list, or similar) + return self.vertices + """ + + def getNeighbors(self, vertex): + """ + GetNeighbors() + Returns a collection of nodes connected to the given node + Takes in a given node + Include the weight of the connection in the returned collection + """ + + if vertex in self.vertices: + return vertex.neighbors + + return 'Provided vertex does not exist in this graph' + + def __len__(self): + return len(self.vertices) \ No newline at end of file diff --git a/data_structures_and_algorithms/data_structures/graph/read.md b/data_structures_and_algorithms/data_structures/graph/read.md new file mode 100644 index 0000000..9cb6d55 --- /dev/null +++ b/data_structures_and_algorithms/data_structures/graph/read.md @@ -0,0 +1,26 @@ +AddVertex() + Adds a new vertex to the graph + Takes in the value of that vertex + Returns the added vertex +AddEdge() + Adds a new edge between two nodes in the graph + Include the ability to have a “weight” + Takes in the two nodes to be connected by the edge + Both nodes should already be in the Graph +GetNodes() + Returns all of the nodes in the graph as a collection (set, list, or similar) +GetNeighbors() + Returns a collection of nodes connected to the given node + Takes in a given node + Include the weight of the connection in the returned collection + + +# Tests +1. Node can be successfully added to the graph +2. An edge can be successfully added to the graph +3. A collection of all nodes can be properly retrieved from the graph +4. All appropriate neighbors can be retrieved from the graph +5. Neighbors are returned with the weight between nodes included +6. The proper size is returned, representing the number of nodes in the graph +7. A graph with only one node and edge can be properly returned +8. An empty graph properly returns null \ No newline at end of file diff --git a/data_structures_and_algorithms/data_structures/graph/test_graph.py b/data_structures_and_algorithms/data_structures/graph/test_graph.py new file mode 100644 index 0000000..6118415 --- /dev/null +++ b/data_structures_and_algorithms/data_structures/graph/test_graph.py @@ -0,0 +1,84 @@ +from graph import Graph +from graph import Vertex + +import pytest + +def test_init_graph_and_vertex(): + + assert Graph + assert Vertex + +def test_add_node_to_graph(): + + + g = Graph() + + test = g.addVertex('potato') + + assert isinstance(test, Vertex) + assert test in g.vertices + assert g.vertices[0].value == 'potato' + +def test_add_edge_to_graph(): + + g = Graph() + + apple = g.addVertex('apple') + banana = g.addVertex('banana') + + g.addEdge(apple, banana, 50) + + assert g.vertices[0].neighbors[0] == {banana, 50} + +def test_add_edge_to_graph_doesnt_add_non_existant(): + + g = Graph() + + apple = g.addVertex('apple') + answer = g.addEdge(apple, 'banana', 50) + + assert answer == 'Please ensure both v1 and v2 exist in the graph' + +def test_get_vertices(): + + g = Graph() + + apple = g.addVertex('apple') + banana = g.addVertex('banana') + cucumber = g.addVertex('cucumber') + + g.getVertices == [apple, banana, cucumber] + + +def test_get_neighbors(): + + g = Graph() + + apple = g.addVertex('apple') + banana = g.addVertex('banana') + cucumber = g.addVertex('cucumber') + durian = Vertex('durian') + + g.addEdge(apple, banana, 45) + g.addEdge(apple, cucumber, 60) + + assert g.getNeighbors(apple) == [{banana, 45}, {cucumber, 60}] + assert g.getNeighbors(durian) == 'Provided vertex does not exist in this graph' + + +def test_graph_length(): + + g = Graph() + h = Graph() + + g.addVertex('apple') + g.addVertex('banana') + g.addVertex('cucumber') + + h.addVertex('apple') + h.addVertex('banana') + h.addVertex('cucumber') + h.addVertex('durian') + + assert len(g) == 3 + assert len(h) == 4 \ No newline at end of file diff --git a/data_structures_and_algorithms/data_structures/linked_list/__pycache__/linked_list.cpython-38.pyc b/data_structures_and_algorithms/data_structures/linked_list/__pycache__/linked_list.cpython-38.pyc index d4bbf7a..32661f2 100644 Binary files a/data_structures_and_algorithms/data_structures/linked_list/__pycache__/linked_list.cpython-38.pyc and b/data_structures_and_algorithms/data_structures/linked_list/__pycache__/linked_list.cpython-38.pyc differ diff --git a/data_structures_and_algorithms/data_structures/stacks_and_queues/__pycache__/stacks_and_queues.cpython-38.pyc b/data_structures_and_algorithms/data_structures/stacks_and_queues/__pycache__/stacks_and_queues.cpython-38.pyc new file mode 100644 index 0000000..2e0d426 Binary files /dev/null and b/data_structures_and_algorithms/data_structures/stacks_and_queues/__pycache__/stacks_and_queues.cpython-38.pyc differ diff --git a/data_structures_and_algorithms/data_structures/stacks_and_queues/__pycache__/test_stacks_and_queues.cpython-38-pytest-6.1.2.pyc b/data_structures_and_algorithms/data_structures/stacks_and_queues/__pycache__/test_stacks_and_queues.cpython-38-pytest-6.1.2.pyc new file mode 100644 index 0000000..c2004c3 Binary files /dev/null and b/data_structures_and_algorithms/data_structures/stacks_and_queues/__pycache__/test_stacks_and_queues.cpython-38-pytest-6.1.2.pyc differ diff --git a/data_structures_and_algorithms/data_structures/stacks_and_queues/read.md b/data_structures_and_algorithms/data_structures/stacks_and_queues/read.md new file mode 100644 index 0000000..127d480 --- /dev/null +++ b/data_structures_and_algorithms/data_structures/stacks_and_queues/read.md @@ -0,0 +1,17 @@ + # Stacks and Queues + + we created a data structure called **Stack** and **Queue** in Python. We used three classes, _Node_ and _Queue_, and _Stack_. + + ### Challenge +- Write queue and stack classes with their methods + +## Approach & Efficiency +Stack : +- Define a method called push +- Define a method called pop +- Define a method called peek + +Queue: +- Define a method called enqueue +- Define a method called dequeue +- Define a method called peek big diff --git a/data_structures_and_algorithms/data_structures/stacks_and_queues/stacks_and_queues.py b/data_structures_and_algorithms/data_structures/stacks_and_queues/stacks_and_queues.py new file mode 100644 index 0000000..385dde2 --- /dev/null +++ b/data_structures_and_algorithms/data_structures/stacks_and_queues/stacks_and_queues.py @@ -0,0 +1,95 @@ +class Node: + def __init__(self, value): + self.value = value + self.next = None + + def __repr__(self): + return f'{self.value}' + + +class Stack: + + def __init__(self): + '''initialize stack with top, bottom and length''' + self.top = None + self.bottom = None + self.length = 0 + + def isEmpty(self): + return self.top == None + + def push(self, value): + '''adds new node to top of stack by pointing it to self.top''' + node = Node(value) + node.next = self.top + self.top = node + self.length += 1 + + def pop(self): + '''Takes item from top of stack and returns it by reassigning the current top + to the next item in the stack. Stores the value in a temp variable to be returned''' + if self.length <= 0: + print('nothing to pop') + return + + temp = self.top + self.top = self.top.next + popped = temp.value + self.length -= 1 + return popped + + def peek(self): + '''prints and returns the top of the stack''' + if self.length <= 0: + print('nothing to peek') + return + print(self.top.value) + return self.top.value + + +class Queue: + + def __init__(self): + '''initializes a queue instance''' + self.front = None + self.rear = None + self.length = 0 + + def isEmpty(self): + return self.front == None + + def enqueue(self, value): + '''appends value to front of queue''' + + self.length += 1 + new_node = Node(value) + + if self.rear == None: + self.front = self.rear = new_node + + return + + self.rear.next = new_node + self.rear = new_node + + def dequeue(self): + '''removes value from front of queue, if length is zero it returns the queue + and prints a message''' + self.length -= 1 + + if self.isEmpty(): + self.queue = [] + print('queue is empty') + return self.queue + + temp = self.front + self.front = temp.next + + if self.front == None: + self.rear = None + + return str(temp.value) + + def peek(self): + '''returns the first value in a queue''' + return self.front.value diff --git a/data_structures_and_algorithms/data_structures/stacks_and_queues/test_stacks_and_queues.py b/data_structures_and_algorithms/data_structures/stacks_and_queues/test_stacks_and_queues.py new file mode 100644 index 0000000..fe403c6 --- /dev/null +++ b/data_structures_and_algorithms/data_structures/stacks_and_queues/test_stacks_and_queues.py @@ -0,0 +1,99 @@ +from stacks_and_queues import Node, Stack, Queue + +def test_empty_stack(): + test_stack = Stack() + assert isinstance(test_stack, Stack) + +def test_push(): + test_stack = Stack() + test_stack.push(1) + test_stack.push(2) + assert test_stack.top.value == 2 + +def test_muliple_nodes(): + test_stack = Stack() + test_stack.push(1) + test_stack.push(2) + test_stack.push(3) + assert test_stack.length == 3 + +def test_pop(): + test_stack = Stack() + test_stack.push(1) + test_stack.push(2) + test_stack.push(3) + popped = test_stack.pop() + assert popped == 3 + assert test_stack.length == 2 + assert test_stack.top.value == 2 + +def test_multipop(): + test_stack = Stack() + test_stack.push(1) + test_stack.push(2) + test_stack.push(3) + test_stack.pop() + test_stack.pop() + test_stack.pop() + assert test_stack.length == 0 + assert test_stack.bottom == None + +def test_peek(): + test_stack = Stack() + test_stack.push(1) + test_stack.push(2) + test_stack.push(3) + + assert test_stack.peek() == 3 + +def test_enqueue(): + q = Queue() + q.enqueue(1) + q.enqueue(2) + q.enqueue(3) + + assert q.front.value == 1 + +def test_enqueue_multiple(): + q = Queue() + q.enqueue(1) + q.enqueue(2) + q.enqueue(3) + + assert q.length == 3 + +def test_dequeue(): + q = Queue() + q.enqueue(1) + q.enqueue(2) + q.enqueue(3) + q.dequeue() + + assert q.length == 2 + assert q.front.value == 2 + +def test_enqueue_empty_queue(): + q = Queue() + q.enqueue(1) + q.enqueue(2) + q.enqueue(3) + q.dequeue() + q.dequeue() + q.dequeue() + + assert q.length == 0 + +def test_instantiate_empty(): + q = Queue() + + assert q.length == 0 + assert q.front == None + + +def test_q_peek(): + q = Queue() + q.enqueue(1) + q.enqueue(2) + q.enqueue(3) + + assert q.peek() == 1 \ No newline at end of file diff --git a/data_structures_and_algorithms/data_structures/tree/__pycache__/tree.cpython-38.pyc b/data_structures_and_algorithms/data_structures/tree/__pycache__/tree.cpython-38.pyc new file mode 100644 index 0000000..65e5d35 Binary files /dev/null and b/data_structures_and_algorithms/data_structures/tree/__pycache__/tree.cpython-38.pyc differ diff --git a/data_structures_and_algorithms/data_structures/tree/resd.md b/data_structures_and_algorithms/data_structures/tree/resd.md new file mode 100644 index 0000000..e216d2e --- /dev/null +++ b/data_structures_and_algorithms/data_structures/tree/resd.md @@ -0,0 +1,76 @@ +Tree Traversals (Inorder, Preorder and Postorder) +Unlike linear data structures (Array, Linked List, Queues, Stacks, etc) which have only one logical way to traverse them, trees can be traversed in different ways. Following are the generally used ways for traversing trees. + + + +Depth First Traversals: +(a) Inorder (Left, Root, Right) : 4 2 5 1 3 +(b) Preorder (Root, Left, Right) : 1 2 4 5 3 +(c) Postorder (Left, Right, Root) : 4 5 2 3 1 + +Breadth First or Level Order Traversal : 1 2 3 4 5 +Please see this post for Breadth First Traversal. + +Inorder Traversal : + +Algorithm Inorder(tree) + 1. Traverse the left subtree, i.e., call Inorder(left-subtree) + 2. Visit the root. + 3. Traverse the right subtree, i.e., call Inorder(right-subtree) +Uses of Inorder +In case of binary search trees (BST), Inorder traversal gives nodes in non-decreasing order. To get nodes of BST in non-increasing order, a variation of Inorder traversal where Inorder traversal s reversed can be used. + + +Preorder Traversal : + +Algorithm Preorder(tree) + 1. Visit the root. + 2. Traverse the left subtree, i.e., call Preorder(left-subtree) + 3. Traverse the right subtree, i.e., call Preorder(right-subtree) +Uses of Preorder +Preorder traversal is used to create a copy of the tree. Preorder traversal is also used to get prefix expression on of an expression tree. + +Postorder Traversal : + +Algorithm Postorder(tree) + 1. Traverse the left subtree, i.e., call Postorder(left-subtree) + 2. Traverse the right subtree, i.e., call Postorder(right-subtree) + 3. Visit the root. +Uses of Postorder +Postorder traversal is used to delete the tree. Please see the question for deletion of tree for details. Postorder traversal is also useful to get the postfix expression of an expression tree. + + +Time Complexity: O(n) +Complexity function T(n) — for all problem where tree traversal is involved — can be defined as: + +T(n) = T(k) + T(n – k – 1) + c + +Where k is the number of nodes on one side of root and n-k-1 on the other side. + +Let’s do an analysis of boundary conditions + +Case 1: Skewed tree (One of the subtrees is empty and other subtree is non-empty ) + +k is 0 in this case. +T(n) = T(0) + T(n-1) + c +T(n) = 2T(0) + T(n-2) + 2c +T(n) = 3T(0) + T(n-3) + 3c +T(n) = 4T(0) + T(n-4) + 4c + +………………………………………… +…………………………………………. +T(n) = (n-1)T(0) + T(1) + (n-1)c +T(n) = nT(0) + (n)c + +Value of T(0) will be some constant say d. (traversing a empty tree will take some constants time) + +T(n) = n(c+d) +T(n) = Θ(n) (Theta of n) + +Case 2: Both left and right subtrees have equal number of nodes. + +T(n) = 2T(|_n/2_|) + c + +This recursive function is in the standard form (T(n) = aT(n/b) + (-)(n) ) + +Auxiliary Space : If we don’t consider size of stack for function calls then O(1) otherwise O(n). \ No newline at end of file diff --git a/data_structures_and_algorithms/data_structures/tree/tree.py b/data_structures_and_algorithms/data_structures/tree/tree.py new file mode 100644 index 0000000..47cbe49 --- /dev/null +++ b/data_structures_and_algorithms/data_structures/tree/tree.py @@ -0,0 +1,125 @@ +class Node: + """Node class definition.""" + + def __init__(self, val=None): + """Create an instance of Node object.""" + self.val = val + self.children = [] + self._next = next + + def __repr__(self): + """Node class representation.""" + return ''.format(self.val) + + def __str__(self): + """Node class string printout.""" + return 'Node Val: {}'.format(self.val) + +class Queue: + def __init__(self, iter=[]): + self.front = None + self.back = None + self._length = 0 + + if not isinstance(iter, (list, dict, tuple)): + """ check for iterable """ + raise TypeError('It is not iterable.') + for i in iter: + self.enqueue(i) + + def enqueue(self, val): + """ add a value, increase size by 1""" + node = Node(val) + if self._length == 0: + self.front = self.back = node + self._length += 1 + return node + self.back.next = node + self.back = node + self._length += 1 + return node + + def dequeue(self): + """ remove node from the front of queue """ + if self._length == 0: + raise IndexError('You cannot dequeue() when front is empty') + + temp = self.front + self.front = temp.next + self._length -= 1 + return temp + +class KTree: + """Ktree class definition.""" + + def __init__(self): + """Create an instance of KTree object.""" + self.root = None + + def __repr__(self): + """Ktree class representation.""" + return ''.format(self.root.val) + + def __str__(self): + """Ktree class string printout.""" + return 'KTree Root Val: {}'.format(self.root.val) + + def pre_order(self, operation): + """Ktree pre_order traversal.""" + def _walk(node=None): + if node is None: + return + + operation(node) + + for child in node.children: + _walk(child) + + _walk(self.root) + + def post_order(self, operation): + """Ktree post_order traversal.""" + def _walk(node=None): + if node is None: + return + + for child in node.children: + _walk(child) + + operation(node) + + _walk(self.root) + + def breadth_first_traversal(self, operation): + """Ktree breadth_first_traversal.""" + queue = Queue() + queue.enqueue(self.root) + while queue._length > 0: + current = queue.dequeue() + operation(current) + for child in current.children: + queue.enqueue(child) + + def insert(self, val, parent=None): + """Insert a value at first instance of given parent.""" + if parent is None: + if self.root is None: + self.root = Node(val) + return self.root + raise ValueError('parent node is none.') + + node = Node(val) + + def _walk(curr=None): + if curr is None: + return + + if curr.val == parent: + curr.children.append(node) + return + + for child in curr.children: + _walk(child) + if node in child.children: + return + _walk(self.root) \ No newline at end of file diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..ca1d6fe --- /dev/null +++ b/poetry.lock @@ -0,0 +1,327 @@ +[[package]] +name = "appdirs" +version = "1.4.4" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "atomicwrites" +version = "1.4.0" +description = "Atomic file writes." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "attrs" +version = "20.3.0" +description = "Classes Without Boilerplate" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] +docs = ["furo", "sphinx", "zope.interface"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] + +[[package]] +name = "binarytree" +version = "5.1.0" +description = "Python Library for Studying Binary Trees" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "black" +version = "19.10b0" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +appdirs = "*" +attrs = ">=18.1.0" +click = ">=6.5" +pathspec = ">=0.6,<1" +regex = "*" +toml = ">=0.9.4" +typed-ast = ">=1.4.0" + +[package.extras] +d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] + +[[package]] +name = "click" +version = "7.1.2" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "more-itertools" +version = "8.6.0" +description = "More routines for operating on iterables, beyond itertools" +category = "dev" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "packaging" +version = "20.8" +description = "Core utilities for Python packages" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +pyparsing = ">=2.0.2" + +[[package]] +name = "pathspec" +version = "0.8.1" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "pluggy" +version = "0.13.1" +description = "plugin and hook calling mechanisms for python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +dev = ["pre-commit", "tox"] + +[[package]] +name = "py" +version = "1.10.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pyparsing" +version = "2.4.7" +description = "Python parsing module" +category = "dev" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "pytest" +version = "5.4.3" +description = "pytest: simple powerful testing with Python" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} +attrs = ">=17.4.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +more-itertools = ">=4.0.0" +packaging = "*" +pluggy = ">=0.12,<1.0" +py = ">=1.5.0" +wcwidth = "*" + +[package.extras] +checkqa-mypy = ["mypy (==v0.761)"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + +[[package]] +name = "regex" +version = "2020.11.13" +description = "Alternative regular expression module, to replace re." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "dev" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "typed-ast" +version = "1.4.1" +description = "a fork of Python 2 and 3 ast modules with type comment support" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "wcwidth" +version = "0.2.5" +description = "Measures the displayed width of unicode strings in a terminal" +category = "dev" +optional = false +python-versions = "*" + +[metadata] +lock-version = "1.1" +python-versions = "^3.8" +content-hash = "2537178073426b12ce677b5516062b1d529794781cf22b6581b101bb8a206c51" + +[metadata.files] +appdirs = [ + {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, + {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +] +atomicwrites = [ + {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, + {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, +] +attrs = [ + {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, + {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, +] +binarytree = [ + {file = "binarytree-5.1.0-py2.py3-none-any.whl", hash = "sha256:9f21efc73c66cdcc88b97b27eb02c3565e46088cf9b0f66089d221a87c8dc557"}, + {file = "binarytree-5.1.0.tar.gz", hash = "sha256:6b8c5f6b298993015a3181f7e6d88e4b0be6632a649cc690a273a653d8dd6b1b"}, +] +black = [ + {file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"}, + {file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"}, +] +click = [ + {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, + {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, +] +colorama = [ + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] +more-itertools = [ + {file = "more-itertools-8.6.0.tar.gz", hash = "sha256:b3a9005928e5bed54076e6e549c792b306fddfe72b2d1d22dd63d42d5d3899cf"}, + {file = "more_itertools-8.6.0-py3-none-any.whl", hash = "sha256:8e1a2a43b2f2727425f2b5839587ae37093f19153dc26c0927d1048ff6557330"}, +] +packaging = [ + {file = "packaging-20.8-py2.py3-none-any.whl", hash = "sha256:24e0da08660a87484d1602c30bb4902d74816b6985b93de36926f5bc95741858"}, + {file = "packaging-20.8.tar.gz", hash = "sha256:78598185a7008a470d64526a8059de9aaa449238f280fc9eb6b13ba6c4109093"}, +] +pathspec = [ + {file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"}, + {file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"}, +] +pluggy = [ + {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, + {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, +] +py = [ + {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, + {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, +] +pyparsing = [ + {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, + {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, +] +pytest = [ + {file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"}, + {file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"}, +] +regex = [ + {file = "regex-2020.11.13-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8b882a78c320478b12ff024e81dc7d43c1462aa4a3341c754ee65d857a521f85"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a63f1a07932c9686d2d416fb295ec2c01ab246e89b4d58e5fa468089cab44b70"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:6e4b08c6f8daca7d8f07c8d24e4331ae7953333dbd09c648ed6ebd24db5a10ee"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:bba349276b126947b014e50ab3316c027cac1495992f10e5682dc677b3dfa0c5"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:56e01daca75eae420bce184edd8bb341c8eebb19dd3bce7266332258f9fb9dd7"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:6a8ce43923c518c24a2579fda49f093f1397dad5d18346211e46f134fc624e31"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:1ab79fcb02b930de09c76d024d279686ec5d532eb814fd0ed1e0051eb8bd2daa"}, + {file = "regex-2020.11.13-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:9801c4c1d9ae6a70aeb2128e5b4b68c45d4f0af0d1535500884d644fa9b768c6"}, + {file = "regex-2020.11.13-cp36-cp36m-win32.whl", hash = "sha256:49cae022fa13f09be91b2c880e58e14b6da5d10639ed45ca69b85faf039f7a4e"}, + {file = "regex-2020.11.13-cp36-cp36m-win_amd64.whl", hash = "sha256:749078d1eb89484db5f34b4012092ad14b327944ee7f1c4f74d6279a6e4d1884"}, + {file = "regex-2020.11.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b2f4007bff007c96a173e24dcda236e5e83bde4358a557f9ccf5e014439eae4b"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:38c8fd190db64f513fe4e1baa59fed086ae71fa45083b6936b52d34df8f86a88"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5862975b45d451b6db51c2e654990c1820523a5b07100fc6903e9c86575202a0"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:262c6825b309e6485ec2493ffc7e62a13cf13fb2a8b6d212f72bd53ad34118f1"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:bafb01b4688833e099d79e7efd23f99172f501a15c44f21ea2118681473fdba0"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:e32f5f3d1b1c663af7f9c4c1e72e6ffe9a78c03a31e149259f531e0fed826512"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:3bddc701bdd1efa0d5264d2649588cbfda549b2899dc8d50417e47a82e1387ba"}, + {file = "regex-2020.11.13-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:02951b7dacb123d8ea6da44fe45ddd084aa6777d4b2454fa0da61d569c6fa538"}, + {file = "regex-2020.11.13-cp37-cp37m-win32.whl", hash = "sha256:0d08e71e70c0237883d0bef12cad5145b84c3705e9c6a588b2a9c7080e5af2a4"}, + {file = "regex-2020.11.13-cp37-cp37m-win_amd64.whl", hash = "sha256:1fa7ee9c2a0e30405e21031d07d7ba8617bc590d391adfc2b7f1e8b99f46f444"}, + {file = "regex-2020.11.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:baf378ba6151f6e272824b86a774326f692bc2ef4cc5ce8d5bc76e38c813a55f"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e3faaf10a0d1e8e23a9b51d1900b72e1635c2d5b0e1bea1c18022486a8e2e52d"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2a11a3e90bd9901d70a5b31d7dd85114755a581a5da3fc996abfefa48aee78af"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1ebb090a426db66dd80df8ca85adc4abfcbad8a7c2e9a5ec7513ede522e0a8f"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:b2b1a5ddae3677d89b686e5c625fc5547c6e492bd755b520de5332773a8af06b"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:2c99e97d388cd0a8d30f7c514d67887d8021541b875baf09791a3baad48bb4f8"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:c084582d4215593f2f1d28b65d2a2f3aceff8342aa85afd7be23a9cad74a0de5"}, + {file = "regex-2020.11.13-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:a3d748383762e56337c39ab35c6ed4deb88df5326f97a38946ddd19028ecce6b"}, + {file = "regex-2020.11.13-cp38-cp38-win32.whl", hash = "sha256:7913bd25f4ab274ba37bc97ad0e21c31004224ccb02765ad984eef43e04acc6c"}, + {file = "regex-2020.11.13-cp38-cp38-win_amd64.whl", hash = "sha256:6c54ce4b5d61a7129bad5c5dc279e222afd00e721bf92f9ef09e4fae28755683"}, + {file = "regex-2020.11.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1862a9d9194fae76a7aaf0150d5f2a8ec1da89e8b55890b1786b8f88a0f619dc"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux1_i686.whl", hash = "sha256:4902e6aa086cbb224241adbc2f06235927d5cdacffb2425c73e6570e8d862364"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7a25fcbeae08f96a754b45bdc050e1fb94b95cab046bf56b016c25e9ab127b3e"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:d2d8ce12b7c12c87e41123997ebaf1a5767a5be3ec545f64675388970f415e2e"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f7d29a6fc4760300f86ae329e3b6ca28ea9c20823df123a2ea8693e967b29917"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:717881211f46de3ab130b58ec0908267961fadc06e44f974466d1887f865bd5b"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:3128e30d83f2e70b0bed9b2a34e92707d0877e460b402faca908c6667092ada9"}, + {file = "regex-2020.11.13-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:8f6a2229e8ad946e36815f2a03386bb8353d4bde368fdf8ca5f0cb97264d3b5c"}, + {file = "regex-2020.11.13-cp39-cp39-win32.whl", hash = "sha256:f8f295db00ef5f8bae530fc39af0b40486ca6068733fb860b42115052206466f"}, + {file = "regex-2020.11.13-cp39-cp39-win_amd64.whl", hash = "sha256:a15f64ae3a027b64496a71ab1f722355e570c3fac5ba2801cafce846bf5af01d"}, + {file = "regex-2020.11.13.tar.gz", hash = "sha256:83d6b356e116ca119db8e7c6fc2983289d87b27b3fac238cfe5dca529d884562"}, +] +toml = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] +typed-ast = [ + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"}, + {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"}, + {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"}, + {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"}, + {file = "typed_ast-1.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:fcf135e17cc74dbfbc05894ebca928ffeb23d9790b3167a674921db19082401f"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"}, + {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"}, + {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"}, + {file = "typed_ast-1.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f208eb7aff048f6bea9586e61af041ddf7f9ade7caed625742af423f6bae3298"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"}, + {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"}, + {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"}, + {file = "typed_ast-1.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7e4c9d7658aaa1fc80018593abdf8598bf91325af6af5cce4ce7c73bc45ea53d"}, + {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"}, + {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"}, + {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"}, + {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:92c325624e304ebf0e025d1224b77dd4e6393f18aab8d829b5b7e04afe9b7a2c"}, + {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d648b8e3bf2fe648745c8ffcee3db3ff903d0817a01a12dd6a6ea7a8f4889072"}, + {file = "typed_ast-1.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:fac11badff8313e23717f3dada86a15389d0708275bddf766cca67a84ead3e91"}, + {file = "typed_ast-1.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:0d8110d78a5736e16e26213114a38ca35cb15b6515d535413b090bd50951556d"}, + {file = "typed_ast-1.4.1-cp39-cp39-win32.whl", hash = "sha256:b52ccf7cfe4ce2a1064b18594381bccf4179c2ecf7f513134ec2f993dd4ab395"}, + {file = "typed_ast-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:3742b32cf1c6ef124d57f95be609c473d7ec4c14d0090e5a5e05a15269fb4d0c"}, + {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, +] +wcwidth = [ + {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, + {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, +] diff --git a/pyproject.toml b/pyproject.toml index 86421c1..651e9a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,7 @@ authors = ["JB "] [tool.poetry.dependencies] python = "^3.8" +binarytree = "^5.1.0" [tool.poetry.dev-dependencies] pytest = "^5.2" diff --git a/tests/challenges/__pycache__/test_array_search.cpython-38-pytest-6.1.2.pyc b/tests/challenges/__pycache__/test_array_search.cpython-38-pytest-6.1.2.pyc index bc729e6..c52c33e 100644 Binary files a/tests/challenges/__pycache__/test_array_search.cpython-38-pytest-6.1.2.pyc and b/tests/challenges/__pycache__/test_array_search.cpython-38-pytest-6.1.2.pyc differ diff --git a/tests/challenges/__pycache__/test_array_shift.cpython-38-pytest-6.1.2.pyc b/tests/challenges/__pycache__/test_array_shift.cpython-38-pytest-6.1.2.pyc index 7a70476..6054f31 100644 Binary files a/tests/challenges/__pycache__/test_array_shift.cpython-38-pytest-6.1.2.pyc and b/tests/challenges/__pycache__/test_array_shift.cpython-38-pytest-6.1.2.pyc differ diff --git a/tests/challenges/__pycache__/test_tree_intersection.cpython-38-pytest-6.1.2.pyc b/tests/challenges/__pycache__/test_tree_intersection.cpython-38-pytest-6.1.2.pyc new file mode 100644 index 0000000..b224d94 Binary files /dev/null and b/tests/challenges/__pycache__/test_tree_intersection.cpython-38-pytest-6.1.2.pyc differ diff --git a/tests/challenges/test_tree_intersection.py b/tests/challenges/test_tree_intersection.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/data_structures/__pycache__/test_linked_list.cpython-38-pytest-6.1.2.pyc b/tests/data_structures/__pycache__/test_linked_list.cpython-38-pytest-6.1.2.pyc index e69de29..0a8683c 100644 Binary files a/tests/data_structures/__pycache__/test_linked_list.cpython-38-pytest-6.1.2.pyc and b/tests/data_structures/__pycache__/test_linked_list.cpython-38-pytest-6.1.2.pyc differ