diff --git a/.ipynb_checkpoints/Untitled-checkpoint.ipynb b/.ipynb_checkpoints/Untitled-checkpoint.ipynb new file mode 100644 index 00000000..a8a9497b --- /dev/null +++ b/.ipynb_checkpoints/Untitled-checkpoint.ipynb @@ -0,0 +1,1074 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 0" + ] + }, + { + "cell_type": "code", + "execution_count": 554, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\n", + "class NodeKey():\n", + " def __init__(self, value, name=None):\n", + " self.name = name\n", + " self.value = value\n", + "\n", + " def __lt__(self, other):\n", + " return self.value < other.value or (self.value == other.value and self.name < other.name)\n", + "\n", + " def __le__(self, other):\n", + " return self < other or self == other\n", + "\n", + " def __eq__(self, other):\n", + " return self.value == other.value and self.name == other.name\n", + "\n", + " def __ne__(self, other):\n", + " return self.value != other.value or self.name != other.name\n", + "\n", + " def __gt__(self, other):\n", + " return self.value > other.value or (self.value == other.value and self.name > other.name)\n", + "\n", + " def __ge__(self, other):\n", + " return self > other or self == other\n", + "\n", + " def __str__(self):\n", + " if self.name is None:\n", + " return str(self.value)\n", + " else:\n", + " return str(self.value) + \",\" + str(self.name)\n", + "\n", + "\n", + "class Node():\n", + " def __init__(self, value, name=None):\n", + " self.key = NodeKey(value, name)\n", + " self.value = value\n", + " self.parent = None\n", + " self.left_child = None\n", + " self.right_child = None\n", + " self.height = 0\n", + "\n", + " def __str__(self):\n", + " return str(self.key)\n", + "\n", + " def next(self):\n", + " \"\"\" Returns the next Node (next key value larger)\n", + " \"\"\"\n", + " # If has right child, select, then traverse left all the way down\n", + " if self.right_child is not None:\n", + " node = self.right_child\n", + " while node.left_child is not None:\n", + " node = node.left_child\n", + " return node\n", + "\n", + " node = self\n", + " # Try to find an ancestor that is a left child, return parent of that\n", + " while node.parent is not None:\n", + " if node.parent.left_child == node:\n", + " return node.parent\n", + " node = node.parent\n", + "\n", + " # Nothing greater than this\n", + " return None\n", + "\n", + " def previous(self):\n", + " \"\"\" Returns the previous Node (next key value smaller)\n", + " \"\"\"\n", + " # If has left child, select, then traverse right all the way down\n", + " if self.left_child is not None:\n", + " node = self.left_child\n", + " while node.right_child is not None:\n", + " node = node.right_child\n", + " return node\n", + "\n", + " node = self\n", + " # Try to find an ancestor that is a right child, return parent of that\n", + " while node.parent is not None:\n", + " if node.parent.right_child == node:\n", + " return node.parent\n", + " node = node.parent\n", + "\n", + " # Nothing smaller than this\n", + " return None\n", + "\n", + " def is_leaf(self):\n", + " \"\"\" Return True if Leaf, False Otherwise\n", + " \"\"\"\n", + " return self.height == 0\n", + "\n", + " def max_child_height(self):\n", + " \"\"\" Return Height Of Tallest Child or -1 if No Children\n", + " \"\"\"\n", + " if self.left_child and self.right_child:\n", + " # two children\n", + " return max(self.left_child.height, self.right_child.height)\n", + " elif self.left_child is not None and self.right_child is None:\n", + " # one child, on left\n", + " return self.left_child.height\n", + " elif self.left_child is None and self.right_child is not None:\n", + " # one child, on right\n", + " return self.right_child.height\n", + " else:\n", + " # no Children\n", + " return -1\n", + "\n", + " def weigh(self):\n", + " \"\"\" Return How Left or Right Sided the Tree Is\n", + " Positive Number Means Left Side Heavy, Negative Number Means Right Side Heavy\n", + " \"\"\"\n", + " if self.left_child is None:\n", + " left_height = -1\n", + " else:\n", + " left_height = self.left_child.height\n", + "\n", + " if self.right_child is None:\n", + " right_height = -1\n", + " else:\n", + " right_height = self.right_child.height\n", + "\n", + " balance = left_height - right_height\n", + " return balance\n", + "\n", + " def update_height(self):\n", + " \"\"\" Updates Height of This Node and All Ancestor Nodes, As Necessary\n", + " \"\"\"\n", + " # TODO: should stop iterating when reaches correct height\n", + " node = self\n", + " while node is not None:\n", + " node.height = node.max_child_height() + 1\n", + " node = node.parent\n", + "\n", + " def root(self):\n", + " node = self\n", + " while node.parent is not None:\n", + " node = node.parent\n", + " return node\n", + "\n", + " def balance(self, tree):\n", + " \"\"\" Balances node, sets new tree root if appropriate\n", + " Note: If balancing does occur, this node will move to a lower position on the tree\n", + " \"\"\"\n", + " while self.weigh() < -1 or self.weigh() > 1:\n", + " if self.weigh() < 0:\n", + " # right side heavy\n", + " if self.right_child.weigh() > 0:\n", + " # right-side left-side heavy\n", + " self.right_child.rotate_left()\n", + " # right-side right-side heavy\n", + " new_top = self.rotate_right()\n", + " else:\n", + " # left side heavy\n", + " if self.left_child.weigh() < 0:\n", + " # left-side right-side heavy\n", + " self.left_child.rotate_right()\n", + " # left-side left-side heavy\n", + " new_top = self.rotate_left()\n", + "\n", + " if new_top.parent is None:\n", + " tree.root = new_top\n", + "\n", + " def out(self):\n", + " \"\"\" Return String Representing Tree From Current Node Down\n", + " Only Works for Small Trees\n", + " \"\"\"\n", + " start_node = self\n", + " space_symbol = \"*\"\n", + " spaces_count = 250\n", + " out_string = \"\"\n", + " initial_spaces_string = space_symbol * spaces_count + \"\\n\"\n", + " if start_node is None:\n", + " return \"AVLTree is empty\"\n", + " else:\n", + " level = [start_node]\n", + " while len([i for i in level if (not i is None)]) > 0:\n", + " level_string = initial_spaces_string\n", + " for i in xrange(len(level)):\n", + " j = (i + 1) * spaces_count / (len(level) + 1)\n", + " level_string = level_string[:j] + (str(level[i]) if level[i] else space_symbol) + level_string[j + 1:]\n", + " level_next = []\n", + " for i in level:\n", + " level_next += ([i.left_child, i.right_child] if i else [None, None])\n", + " level = level_next\n", + " out_string += level_string\n", + " return out_string\n", + "\n", + " def rotate_right(self):\n", + " assert(self.right_child is not None)\n", + " to_promote = self.right_child\n", + " swapper = to_promote.left_child\n", + "\n", + " # swap children\n", + " self.right_child = swapper\n", + " to_promote.left_child = self\n", + " new_top = self._swap_parents(to_promote, swapper)\n", + " if swapper is not None:\n", + " swapper.update_height()\n", + " self.update_height()\n", + " return new_top\n", + "\n", + " def rotate_left(self):\n", + " assert(self.left_child is not None)\n", + " to_promote = self.left_child\n", + " swapper = to_promote.right_child\n", + "\n", + " # swap children\n", + " self.left_child = swapper\n", + " to_promote.right_child = self\n", + " new_top = self._swap_parents(to_promote, swapper)\n", + " if swapper is not None:\n", + " swapper.update_height()\n", + " self.update_height()\n", + " return new_top\n", + "\n", + " def _swap_parents(self, promote, swapper):\n", + " \"\"\" re-assign parents, returns new top\n", + " \"\"\"\n", + " promote.parent = self.parent\n", + " self.parent = promote\n", + " if swapper is not None:\n", + " swapper.parent = self\n", + "\n", + " if promote.parent is not None:\n", + " if promote.parent.right_child == self:\n", + " promote.parent.right_child = promote\n", + " elif promote.parent.left_child == self:\n", + " promote.parent.left_child = promote\n", + " return promote\n", + "\n", + "\n", + "class BinaryTree():\n", + " \"\"\" Binary Search Tree\n", + " Uses AVL Tree\n", + " \"\"\"\n", + " def __init__(self, *args):\n", + " self.root = None # root Node\n", + " self.element_count = 0\n", + " if len(args) == 1:\n", + " for i in args[0]:\n", + " self.insert(i)\n", + "\n", + " def __len__(self):\n", + " return self.element_count\n", + "\n", + " def __str__(self):\n", + " return self.out()\n", + "\n", + " def height(self):\n", + " \"\"\" Return Max Height Of Tree\n", + " \"\"\"\n", + " if self.root:\n", + " return self.root.height\n", + " else:\n", + " return 0\n", + "\n", + " def balance(self):\n", + " \"\"\" Perform balancing Operation\n", + " \"\"\"\n", + " if self.root is not None:\n", + " self.root.balance(self)\n", + "\n", + " def insert(self, value, name=None):\n", + " if self.root is None:\n", + " # If nothing in tree\n", + " self.root = Node(value, name)\n", + " else:\n", + " if self.find(value, name) is None:\n", + " # If key/name pair doesn't exist in tree\n", + " self.element_count += 1\n", + " self.add_as_child(self.root, Node(value, name))\n", + "\n", + " def add_as_child(self, parent_node, child_node):\n", + " if child_node.key < parent_node.key:\n", + " # should go on left\n", + " if parent_node.left_child is None:\n", + " # can add to this node\n", + " parent_node.left_child = child_node\n", + " child_node.parent = parent_node\n", + " child_node.update_height()\n", + " else:\n", + " self.add_as_child(parent_node.left_child, child_node)\n", + " else:\n", + " # should go on right\n", + " if parent_node.right_child is None:\n", + " # can add to this node\n", + " parent_node.right_child = child_node\n", + " child_node.parent = parent_node\n", + " child_node.update_height()\n", + " else:\n", + " self.add_as_child(parent_node.right_child, child_node)\n", + "\n", + " if parent_node.weigh() not in [-1, 0, 1]:\n", + " parent_node.balance(self)\n", + "\n", + " def inorder_non_recursive(self):\n", + " node = self.root\n", + " retlst = []\n", + " while node.left_child:\n", + " node = node.left_child\n", + " while node:\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " if node.right_child:\n", + " node = node.right_child\n", + " while node.left_child:\n", + " node = node.left_child\n", + " else:\n", + " while node.parent and (node == node.parent.right_child):\n", + " node = node.parent\n", + " node = node.parent\n", + " return retlst\n", + "\n", + " def preorder(self, node, retlst=None):\n", + " if retlst is None:\n", + " retlst = []\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " if node.left_child:\n", + " retlst = self.preorder(node.left_child, retlst)\n", + " if node.right_child:\n", + " retlst = self.preorder(node.right_child, retlst)\n", + " return retlst\n", + "\n", + " def inorder(self, node, retlst=None):\n", + " if retlst is None:\n", + " retlst = []\n", + " if node.left_child:\n", + " retlst = self.inorder(node.left_child, retlst)\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " if node.right_child:\n", + " retlst = self.inorder(node.right_child, retlst)\n", + " return retlst\n", + "\n", + " def postorder(self, node, retlst=None):\n", + " if retlst is None:\n", + " retlst = []\n", + " if node.left_child:\n", + " retlst = self.postorder(node.left_child, retlst)\n", + " if node.right_child:\n", + " retlst = self.postorder(node.right_child, retlst)\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " return retlst\n", + "\n", + " def as_list(self, pre_in_post):\n", + " if not self.root:\n", + " return []\n", + " if pre_in_post == 0:\n", + " return self.preorder(self.root)\n", + " elif pre_in_post == 1:\n", + " return self.inorder(self.root)\n", + " elif pre_in_post == 2:\n", + " return self.postorder(self.root)\n", + " elif pre_in_post == 3:\n", + " return self.inorder_non_recursive()\n", + "\n", + " def find(self, value, name=None):\n", + " return self.find_in_subtree(self.root, NodeKey(value, name))\n", + "\n", + " def find_in_subtree(self, node, node_key):\n", + " if node is None:\n", + " return None # key not found\n", + " if node_key < node.key:\n", + " return self.find_in_subtree(node.left_child, node_key)\n", + " elif node_key > node.key:\n", + " return self.find_in_subtree(node.right_child, node_key)\n", + " else: # key is equal to node key\n", + " return node\n", + "\n", + " def remove(self, key):\n", + " # first find\n", + " node = self.find(key)\n", + "\n", + " if not node is None:\n", + " self.element_count -= 1\n", + "\n", + " if node.is_leaf():\n", + " # The node is a leaf. Remove it and return.\n", + " self.remove_leaf(node)\n", + " elif (node.left_child is not None and node.right_child is None) or (node.left_child is None and node.right_child is not None):\n", + " # The node has only 1 child. Make the pointer to this node point to the child of this node.\n", + " self.remove_branch(node)\n", + " else:\n", + " # The node has 2 children. Swap items with the successor (the smallest item in its right subtree) and\n", + " # delete the successor from the right subtree of the node.\n", + " assert node.left_child and node.right_child\n", + " self.swap_with_successor_and_remove(node)\n", + "\n", + " def remove_leaf(self, node):\n", + " parent = node.parent\n", + " if parent:\n", + " if parent.left_child == node:\n", + " parent.left_child = None\n", + " else:\n", + " assert (parent.right_child == node)\n", + " parent.right_child = None\n", + " parent.update_height()\n", + " else:\n", + " self.root = None\n", + "\n", + " # rebalance\n", + " node = parent\n", + " while node:\n", + " if not node.weigh() in [-1, 0, 1]:\n", + " node.balance(self)\n", + " node = node.parent\n", + "\n", + " def remove_branch(self, node):\n", + " parent = node.parent\n", + " if parent:\n", + " if parent.left_child == node:\n", + " parent.left_child = node.right_child or node.left_child\n", + " else:\n", + " assert (parent.right_child == node)\n", + " parent.right_child = node.right_child or node.left_child\n", + "\n", + " if node.left_child:\n", + " node.left_child.parent = parent\n", + " else:\n", + " assert node.right_child\n", + " node.right_child.parent = parent\n", + " parent.update_height()\n", + "\n", + " # rebalance\n", + " node = parent\n", + " while node:\n", + " if not node.weigh() in [-1, 0, 1]:\n", + " node.balance(self)\n", + " node = node.parent\n", + "\n", + " def swap_with_successor_and_remove(self, node):\n", + " successor = node.right_child\n", + " while successor.left_child:\n", + " successor = successor.left_child\n", + " self.swap_nodes(node, successor)\n", + " assert (node.left_child is None)\n", + " if node.height == 0:\n", + " self.remove_leaf(node)\n", + " else:\n", + " self.remove_branch(node)\n", + "\n", + " def swap_nodes(self, node_1, node_2):\n", + " assert (node_1.height > node_2.height)\n", + " parent_1 = node_1.parent\n", + " left_child_1 = node_1.left_child\n", + " right_child_1 = node_1.right_child\n", + " parent_2 = node_2.parent\n", + " assert (not parent_2 is None)\n", + " assert (parent_2.left_child == node_2 or parent_2 == node_1)\n", + " left_child_2 = node_2.left_child\n", + " assert (left_child_2 is None)\n", + " right_child_2 = node_2.right_child\n", + "\n", + " # swap heights\n", + " tmp = node_1.height\n", + " node_1.height = node_2.height\n", + " node_2.height = tmp\n", + "\n", + " if parent_1:\n", + " if parent_1.left_child == node_1:\n", + " parent_1.left_child = node_2\n", + " else:\n", + " assert (parent_1.right_child == node_1)\n", + " parent_1.right_child = node_2\n", + " node_2.parent = parent_1\n", + " else:\n", + " self.root = node_2\n", + " node_2.parent = None\n", + "\n", + " node_2.left_child = left_child_1\n", + " left_child_1.parent = node_2\n", + " node_1.left_child = left_child_2 # None\n", + " node_1.right_child = right_child_2\n", + " if right_child_2:\n", + " right_child_2.parent = node_1\n", + " if not (parent_2 == node_1):\n", + " node_2.right_child = right_child_1\n", + " right_child_1.parent = node_2\n", + "\n", + " parent_2.left_child = node_1\n", + " node_1.parent = parent_2\n", + " else:\n", + " node_2.right_child = node_1\n", + " node_1.parent = node_2\n", + "\n", + " # use for debug only and only with small trees\n", + "\n", + " def out(self, start_node=None):\n", + " if start_node is None:\n", + " start_node = self.root\n", + "\n", + " if start_node is None:\n", + " return None\n", + " else:\n", + " return start_node.out()\n", + "\n", + "\n", + " def find_closest_to_the_left_strict(self,node_tmp,new_node_find):\n", + " if not node_tmp:\n", + " return None\n", + " if node_tmp.key >= new_node_find:\n", + " left_node_result = self.find_closest_to_the_left_strict(node_tmp.left_child,new_node_find)\n", + " if left_node_result:\n", + " return left_node_result\n", + " else:\n", + " return None\n", + " else:\n", + " right_node_result = self.find_closest_to_the_left_strict(node_tmp.right_child,new_node_find)\n", + " if right_node_result:\n", + " return right_node_result\n", + " else:\n", + " return node_tmp\n", + "\n", + " def find_closest_to_the_left_strict_value_only(self,value):\n", + " return self.find_closest_to_the_left_strict(self.root,NodeKey(value))\n", + "\n", + " def find_closest_to_the_right_strict(self,node_tmp,new_node_find):\n", + " if not node_tmp:\n", + " return None\n", + " if node_tmp.key > new_node_find:\n", + " left_node_result = self.find_closest_to_the_right_strict(node_tmp.left_child,new_node_find)\n", + " if left_node_result:\n", + " return left_node_result\n", + " else:\n", + " return node_tmp\n", + " else:\n", + " right_node_result = self.find_closest_to_the_right_strict(node_tmp.right_child,new_node_find)\n", + " if right_node_result:\n", + " return right_node_result\n", + " else:\n", + " return None\n", + "\n", + " def find_closest_to_the_right_strict_value_only(self,value):\n", + " return self.find_closest_to_the_right_strict(self.root,NodeKey(value))\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 555, + "metadata": {}, + "outputs": [], + "source": [ + "btree = BinaryTree()" + ] + }, + { + "cell_type": "code", + "execution_count": 556, + "metadata": {}, + "outputs": [], + "source": [ + "for i in range(1000):\n", + " rand_now = random.randint(0,100)\n", + "\n", + " btree.insert(rand_now)\n", + "btree.insert(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 557, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]\n" + ] + } + ], + "source": [ + "print btree.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 559, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.Node instance at 0x7f678ef58560>" + ] + }, + "execution_count": 559, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree.find(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 560, + "metadata": {}, + "outputs": [], + "source": [ + "btree.remove(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 561, + "metadata": {}, + "outputs": [], + "source": [ + "btree.find(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 562, + "metadata": {}, + "outputs": [], + "source": [ + "sorted_btree_list = btree.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 563, + "metadata": {}, + "outputs": [], + "source": [ + "root_node_now = btree.root" + ] + }, + { + "cell_type": "code", + "execution_count": 564, + "metadata": {}, + "outputs": [], + "source": [ + "new_node_find = NodeKey(14)" + ] + }, + { + "cell_type": "code", + "execution_count": 565, + "metadata": {}, + "outputs": [], + "source": [ + "node_tmp = root_node_now" + ] + }, + { + "cell_type": "code", + "execution_count": 566, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9" + ] + }, + "execution_count": 566, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree.find_closest_to_the_left_strict_value_only(10).value" + ] + }, + { + "cell_type": "code", + "execution_count": 567, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 567, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "btree.find_closest_to_the_left_strict_value_only(10.1).value" + ] + }, + { + "cell_type": "code", + "execution_count": 568, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]\n" + ] + } + ], + "source": [ + "print btree.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 569, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12" + ] + }, + "execution_count": 569, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree.find_closest_to_the_right_strict_value_only(10.1).value" + ] + }, + { + "cell_type": "code", + "execution_count": 570, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "13" + ] + }, + "execution_count": 570, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree.find_closest_to_the_right_strict_value_only(12).value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 571, + "metadata": {}, + "outputs": [], + "source": [ + "def find_closest_to_the_left_strict(node_tmp,new_node_find):\n", + " if not node_tmp:\n", + " return None\n", + " if node_tmp.key >= new_node_find:\n", + " left_node_result = find_closest_to_the_left_strict(node_tmp.left_child,new_node_find)\n", + " if left_node_result:\n", + " return left_node_result\n", + " else:\n", + " return None \n", + " else:\n", + " right_node_result = find_closest_to_the_left_strict(node_tmp.right_child,new_node_find)\n", + " if right_node_result:\n", + " return right_node_result\n", + " else:\n", + " return node_tmp" + ] + }, + { + "cell_type": "code", + "execution_count": 547, + "metadata": {}, + "outputs": [], + "source": [ + "def find_closest_to_the_right_strict(node_tmp,new_node_find):\n", + " if not node_tmp:\n", + " return None\n", + " if node_tmp.key > new_node_find:\n", + " left_node_result = find_closest_to_the_right_strict(node_tmp.left_child,new_node_find)\n", + " if left_node_result:\n", + " return left_node_result\n", + " else:\n", + " return node_tmp \n", + " else:\n", + " right_node_result = find_closest_to_the_right_strict(node_tmp.right_child,new_node_find)\n", + " if right_node_result:\n", + " return right_node_result\n", + " else:\n", + " return None" + ] + }, + { + "cell_type": "code", + "execution_count": 548, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "59" + ] + }, + "execution_count": 548, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result_59 = find_closest_to_the_right_strict(btree.root,NodeKey(58.1))\n", + "result_59.value" + ] + }, + { + "cell_type": "code", + "execution_count": 515, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "60" + ] + }, + "execution_count": 515, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result_60 = find_closest_to_the_right_strict(btree.root,NodeKey(59))\n", + "result_60.value" + ] + }, + { + "cell_type": "code", + "execution_count": 519, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "78" + ] + }, + "execution_count": 519, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result_60 = find_closest_to_the_right_strict(btree.root,NodeKey(77))\n", + "result_60.value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 516, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "58" + ] + }, + "execution_count": 516, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result_58 = find_closest_to_the_left_strict(btree.root,NodeKey(58.1))\n", + "result_58.value" + ] + }, + { + "cell_type": "code", + "execution_count": 517, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9" + ] + }, + "execution_count": 517, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result_58 = find_closest_to_the_left_strict(btree.root,NodeKey(9.1))\n", + "result_58.value" + ] + }, + { + "cell_type": "code", + "execution_count": 518, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "8" + ] + }, + "execution_count": 518, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result_58 = find_closest_to_the_left_strict(btree.root,NodeKey(9))\n", + "result_58.value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/.ipynb_checkpoints/Untitled1-checkpoint.ipynb b/.ipynb_checkpoints/Untitled1-checkpoint.ipynb new file mode 100644 index 00000000..ea92ffa3 --- /dev/null +++ b/.ipynb_checkpoints/Untitled1-checkpoint.ipynb @@ -0,0 +1,4257 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# import binary search tree dict" + ] + }, + { + "cell_type": "code", + "execution_count": 445, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def binary_search_left_on_sorted_array(array, target,cmp = None, mode= None):\n", + " # tell if we can find the target, if yes, return, True, and one element, otherwise\n", + " \"\"\"\n", + " \"\"\"\n", + " lower = 0\n", + " upper = len(array)\n", + " succeed = False\n", + "\n", + " while lower < upper:\n", + " x = lower + (upper - lower) // 2\n", + " val = array[x]\n", + " if cmp is None:\n", + " if target == val:\n", + " if mode == None:\n", + " succeed = True\n", + " break\n", + " elif target > val:\n", + " if lower == x:\n", + "\n", + " break\n", + " lower = x\n", + " elif target < val:\n", + " upper = x\n", + " else:\n", + " if cmp(target,val) == 0:\n", + " succeed = True\n", + " break\n", + " elif cmp(target,val) == 1:\n", + " if lower == x:\n", + " break\n", + " lower = x\n", + " elif cmp(target,val) == -1:\n", + " upper = x\n", + "\n", + " if cmp is None:\n", + " lowest_larger_than_target = array[lower] > target\n", + " else:\n", + " if cmp(target, array[lower]) == -1:\n", + " lowest_larger_than_target = True\n", + "\n", + " if succeed:\n", + " return succeed, x\n", + " elif not succeed and array[lower] > target:\n", + " return succeed, -1\n", + " else:\n", + " return succeed, lower\n", + "\n", + "def simple_insort(array,x,cmp=None,mode= None):\n", + " \"\"\"Insert item x in list a, and keep it sorted assuming a is sorted.\n", + " \"\"\"\n", + " found_element, idx_on_the_left =binary_search_left_on_sorted_array(array,x,cmp,mode)\n", + " where_to_insert = idx_on_the_left + 1\n", + " array.insert(where_to_insert, x)\n", + " return where_to_insert\n", + "\n", + "\n", + "\n", + "def bisect_right(a, x, lo=0, hi=None, cmp = None):\n", + " \"\"\"Return the index where to insert item x in list a, assuming a is sorted.\n", + " The return value i is such that all e in a[:i] have e <= x, and all e in\n", + " a[i:] have e > x. So if x already appears in the list, a.insert(x) will\n", + " insert just after the rightmost x already there.\n", + " Optional args lo (default 0) and hi (default len(a)) bound the\n", + " slice of a to be searched.\n", + " \"\"\"\n", + "\n", + " if lo < 0:\n", + " raise ValueError('lo must be non-negative')\n", + " if hi is None:\n", + " hi = len(a)\n", + " while lo < hi:\n", + " mid = (lo+hi)//2\n", + " if not cmp is None:\n", + " if cmp(x,a[mid])==-1: hi = mid\n", + " else: lo = mid+1\n", + " else:\n", + " if x < a[mid]: hi = mid\n", + " else: lo = mid+1\n", + "\n", + " if not cmp is None:\n", + " if cmp(x,a[lo-1])==0:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + " else:\n", + " if a[lo-1]== x:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + "\n", + " return lo, matched\n", + "\n", + "def bisect_left(a, x, lo=0, hi=None, cmp = None):\n", + " \"\"\"Return the index where to insert item x in list a, assuming a is sorted.\n", + " The return value i is such that all e in a[:i] have e < x, and all e in\n", + " a[i:] have e >= x. So if x already appears in the list, a.insert(x) will\n", + " insert just before the leftmost x already there.\n", + " Optional args lo (default 0) and hi (default len(a)) bound the\n", + " slice of a to be searched.\n", + " \"\"\"\n", + "\n", + " if lo < 0:\n", + " raise ValueError('lo must be non-negative')\n", + " if hi is None:\n", + " hi = len(a)\n", + "\n", + " hi_record = hi\n", + " while lo < hi:\n", + " mid = (lo+hi)//2\n", + "\n", + " if not cmp is None:\n", + " if a[mid] < x: lo = mid+1\n", + " else: hi = mid\n", + " else:\n", + " if a[mid] < x: lo = mid+1\n", + " else: hi = mid\n", + "\n", + " if lo >= hi_record:\n", + " matched=False\n", + " else:\n", + " if not cmp is None:\n", + " if cmp(x,a[lo])==0:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + " else:\n", + " if a[lo]== x:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + "\n", + "\n", + "\n", + " return lo, matched\n", + "\n", + "def insort_right(a, x, lo=0, hi=None,cmp = None):\n", + " \"\"\"Insert item x in list a, and keep it sorted assuming a is sorted.\n", + " If x is already in a, insert it to the right of the rightmost x.\n", + " Optional args lo (default 0) and hi (default len(a)) bound the\n", + " slice of a to be searched.\n", + " \"\"\"\n", + " lo, matched = bisect_right(a, x, lo, hi, cmp)\n", + " a.insert(lo, x)\n", + " return lo\n", + "\n", + "def insort_left(a, x, lo=0, hi=None,cmp = None):\n", + " \"\"\"Insert item x in list a, and keep it sorted assuming a is sorted.\n", + " If x is already in a, insert it to the left of the leftmost x.\n", + " Optional args lo (default 0) and hi (default len(a)) bound the\n", + " slice of a to be searched.\n", + " \"\"\"\n", + " lo, matched = bisect_left(a, x, lo, hi, cmp)\n", + " a.insert(lo, x)\n", + " return lo\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 447, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "\n", + "def bisect_right(a, x, lo=0, hi=None, cmp = None):\n", + " \"\"\"Return the index where to insert item x in list a, assuming a is sorted.\n", + " The return value i is such that all e in a[:i] have e <= x, and all e in\n", + " a[i:] have e > x. So if x already appears in the list, a.insert(x) will\n", + " insert just after the rightmost x already there.\n", + " Optional args lo (default 0) and hi (default len(a)) bound the\n", + " slice of a to be searched.\n", + " \"\"\"\n", + "\n", + " if lo < 0:\n", + " raise ValueError('lo must be non-negative')\n", + " if hi is None:\n", + " hi = len(a)\n", + " while lo < hi:\n", + " mid = (lo+hi)//2\n", + " if not cmp is None:\n", + " if cmp(x,a[mid])==-1: hi = mid\n", + " else: lo = mid+1\n", + " else:\n", + " if x < a[mid]: hi = mid\n", + " else: lo = mid+1\n", + "\n", + " if not cmp is None:\n", + " if cmp(x,a[lo-1])==0:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + " else:\n", + " if a[lo-1]== x:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + "\n", + " return lo, matched\n", + "\n", + "def bisect_left(a, x, lo=0, hi=None, cmp = None):\n", + " \"\"\"Return the index where to insert item x in list a, assuming a is sorted.\n", + " The return value i is such that all e in a[:i] have e < x, and all e in\n", + " a[i:] have e >= x. So if x already appears in the list, a.insert(x) will\n", + " insert just before the leftmost x already there.\n", + " Optional args lo (default 0) and hi (default len(a)) bound the\n", + " slice of a to be searched.\n", + " \"\"\"\n", + "\n", + " if lo < 0:\n", + " raise ValueError('lo must be non-negative')\n", + " if hi is None:\n", + " hi = len(a)\n", + "\n", + " hi_record = hi\n", + " while lo < hi:\n", + " mid = (lo+hi)//2\n", + "\n", + " if not cmp is None:\n", + " if a[mid] < x: lo = mid+1\n", + " else: hi = mid\n", + " else:\n", + " if a[mid] < x: lo = mid+1\n", + " else: hi = mid\n", + "\n", + " if lo >= hi_record:\n", + " matched=False\n", + " else:\n", + " if not cmp is None:\n", + " if cmp(x,a[lo])==0:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + " else:\n", + " if a[lo]== x:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + "\n", + "\n", + "\n", + " return lo, matched\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "\n", + "class NodeKey():\n", + " def __init__(self, value, name=None):\n", + " self.name = name\n", + " self.value = value\n", + "\n", + " def __lt__(self, other):\n", + " return self.value < other.value or (self.value == other.value and self.name < other.name)\n", + "\n", + " def __le__(self, other):\n", + " return self < other or self == other\n", + "\n", + " def __eq__(self, other):\n", + " return self.value == other.value and self.name == other.name\n", + "\n", + " def __ne__(self, other):\n", + " return self.value != other.value or self.name != other.name\n", + "\n", + " def __gt__(self, other):\n", + " return self.value > other.value or (self.value == other.value and self.name > other.name)\n", + "\n", + " def __ge__(self, other):\n", + " return self > other or self == other\n", + "\n", + " def __str__(self):\n", + " if self.name is None:\n", + " return str(self.value)\n", + " else:\n", + " return str(self.value) + \",\" + str(self.name)\n", + "\n", + "\n", + "class Node():\n", + " def __init__(self, value, name=None):\n", + " self.key = NodeKey(value, name)\n", + " self.value = value\n", + " self.parent = None\n", + " self.left_child = None\n", + " self.right_child = None\n", + " self.height = 0\n", + "\n", + " def __str__(self):\n", + " return str(self.key)\n", + "\n", + " def next(self):\n", + " \"\"\" Returns the next Node (next key value larger)\n", + " \"\"\"\n", + " # If has right child, select, then traverse left all the way down\n", + " if self.right_child is not None:\n", + " node = self.right_child\n", + " while node.left_child is not None:\n", + " node = node.left_child\n", + " return node\n", + "\n", + " node = self\n", + " # Try to find an ancestor that is a left child, return parent of that\n", + " while node.parent is not None:\n", + " if node.parent.left_child == node:\n", + " return node.parent\n", + " node = node.parent\n", + "\n", + " # Nothing greater than this\n", + " return None\n", + "\n", + " def previous(self):\n", + " \"\"\" Returns the previous Node (next key value smaller)\n", + " \"\"\"\n", + " # If has left child, select, then traverse right all the way down\n", + " if self.left_child is not None:\n", + " node = self.left_child\n", + " while node.right_child is not None:\n", + " node = node.right_child\n", + " return node\n", + "\n", + " node = self\n", + " # Try to find an ancestor that is a right child, return parent of that\n", + " while node.parent is not None:\n", + " if node.parent.right_child == node:\n", + " return node.parent\n", + " node = node.parent\n", + "\n", + " # Nothing smaller than this\n", + " return None\n", + "\n", + " def is_leaf(self):\n", + " \"\"\" Return True if Leaf, False Otherwise\n", + " \"\"\"\n", + " return self.height == 0\n", + "\n", + " def max_child_height(self):\n", + " \"\"\" Return Height Of Tallest Child or -1 if No Children\n", + " \"\"\"\n", + " if self.left_child and self.right_child:\n", + " # two children\n", + " return max(self.left_child.height, self.right_child.height)\n", + " elif self.left_child is not None and self.right_child is None:\n", + " # one child, on left\n", + " return self.left_child.height\n", + " elif self.left_child is None and self.right_child is not None:\n", + " # one child, on right\n", + " return self.right_child.height\n", + " else:\n", + " # no Children\n", + " return -1\n", + "\n", + " def weigh(self):\n", + " \"\"\" Return How Left or Right Sided the Tree Is\n", + " Positive Number Means Left Side Heavy, Negative Number Means Right Side Heavy\n", + " \"\"\"\n", + " if self.left_child is None:\n", + " left_height = -1\n", + " else:\n", + " left_height = self.left_child.height\n", + "\n", + " if self.right_child is None:\n", + " right_height = -1\n", + " else:\n", + " right_height = self.right_child.height\n", + "\n", + " balance = left_height - right_height\n", + " return balance\n", + "\n", + " def update_height(self):\n", + " \"\"\" Updates Height of This Node and All Ancestor Nodes, As Necessary\n", + " \"\"\"\n", + " # TODO: should stop iterating when reaches correct height\n", + " node = self\n", + " while node is not None:\n", + " node.height = node.max_child_height() + 1\n", + " node = node.parent\n", + "\n", + " def root(self):\n", + " node = self\n", + " while node.parent is not None:\n", + " node = node.parent\n", + " return node\n", + "\n", + " def balance(self, tree):\n", + " \"\"\" Balances node, sets new tree root if appropriate\n", + " Note: If balancing does occur, this node will move to a lower position on the tree\n", + " \"\"\"\n", + " while self.weigh() < -1 or self.weigh() > 1:\n", + " if self.weigh() < 0:\n", + " # right side heavy\n", + " if self.right_child.weigh() > 0:\n", + " # right-side left-side heavy\n", + " self.right_child.rotate_left()\n", + " # right-side right-side heavy\n", + " new_top = self.rotate_right()\n", + " else:\n", + " # left side heavy\n", + " if self.left_child.weigh() < 0:\n", + " # left-side right-side heavy\n", + " self.left_child.rotate_right()\n", + " # left-side left-side heavy\n", + " new_top = self.rotate_left()\n", + "\n", + " if new_top.parent is None:\n", + " tree.root = new_top\n", + "\n", + " def out(self):\n", + " \"\"\" Return String Representing Tree From Current Node Down\n", + " Only Works for Small Trees\n", + " \"\"\"\n", + " start_node = self\n", + " space_symbol = \"*\"\n", + " spaces_count = 250\n", + " out_string = \"\"\n", + " initial_spaces_string = space_symbol * spaces_count + \"\\n\"\n", + " if start_node is None:\n", + " return \"AVLTree is empty\"\n", + " else:\n", + " level = [start_node]\n", + " while len([i for i in level if (not i is None)]) > 0:\n", + " level_string = initial_spaces_string\n", + " for i in xrange(len(level)):\n", + " j = (i + 1) * spaces_count / (len(level) + 1)\n", + " level_string = level_string[:j] + (str(level[i]) if level[i] else space_symbol) + level_string[j + 1:]\n", + " level_next = []\n", + " for i in level:\n", + " level_next += ([i.left_child, i.right_child] if i else [None, None])\n", + " level = level_next\n", + " out_string += level_string\n", + " return out_string\n", + "\n", + " def rotate_right(self):\n", + " assert(self.right_child is not None)\n", + " to_promote = self.right_child\n", + " swapper = to_promote.left_child\n", + "\n", + " # swap children\n", + " self.right_child = swapper\n", + " to_promote.left_child = self\n", + " new_top = self._swap_parents(to_promote, swapper)\n", + " if swapper is not None:\n", + " swapper.update_height()\n", + " self.update_height()\n", + " return new_top\n", + "\n", + " def rotate_left(self):\n", + " assert(self.left_child is not None)\n", + " to_promote = self.left_child\n", + " swapper = to_promote.right_child\n", + "\n", + " # swap children\n", + " self.left_child = swapper\n", + " to_promote.right_child = self\n", + " new_top = self._swap_parents(to_promote, swapper)\n", + " if swapper is not None:\n", + " swapper.update_height()\n", + " self.update_height()\n", + " return new_top\n", + "\n", + " def _swap_parents(self, promote, swapper):\n", + " \"\"\" re-assign parents, returns new top\n", + " \"\"\"\n", + " promote.parent = self.parent\n", + " self.parent = promote\n", + " if swapper is not None:\n", + " swapper.parent = self\n", + "\n", + " if promote.parent is not None:\n", + " if promote.parent.right_child == self:\n", + " promote.parent.right_child = promote\n", + " elif promote.parent.left_child == self:\n", + " promote.parent.left_child = promote\n", + " return promote\n", + "\n", + "\n", + "class BinaryTree():\n", + " \"\"\" Binary Search Tree\n", + " Uses AVL Tree\n", + " \"\"\"\n", + " def __init__(self, *args):\n", + " self.root = None # root Node\n", + " self.element_count = 0\n", + " if len(args) == 1:\n", + " for i in args[0]:\n", + " self.insert(i)\n", + "\n", + " def __len__(self):\n", + " return self.element_count\n", + "\n", + " def __str__(self):\n", + " return self.out()\n", + "\n", + " def height(self):\n", + " \"\"\" Return Max Height Of Tree\n", + " \"\"\"\n", + " if self.root:\n", + " return self.root.height\n", + " else:\n", + " return 0\n", + "\n", + " def balance(self):\n", + " \"\"\" Perform balancing Operation\n", + " \"\"\"\n", + " if self.root is not None:\n", + " self.root.balance(self)\n", + "\n", + " def insert(self, value, name=None):\n", + " if self.root is None:\n", + " # If nothing in tree\n", + " self.root = Node(value, name)\n", + " else:\n", + " if self.find(value, name) is None:\n", + " # If key/name pair doesn't exist in tree\n", + " self.element_count += 1\n", + " self.add_as_child(self.root, Node(value, name))\n", + "\n", + " def add_as_child(self, parent_node, child_node):\n", + " if child_node.key < parent_node.key:\n", + " # should go on left\n", + " if parent_node.left_child is None:\n", + " # can add to this node\n", + " parent_node.left_child = child_node\n", + " child_node.parent = parent_node\n", + " child_node.update_height()\n", + " else:\n", + " self.add_as_child(parent_node.left_child, child_node)\n", + " else:\n", + " # should go on right\n", + " if parent_node.right_child is None:\n", + " # can add to this node\n", + " parent_node.right_child = child_node\n", + " child_node.parent = parent_node\n", + " child_node.update_height()\n", + " else:\n", + " self.add_as_child(parent_node.right_child, child_node)\n", + "\n", + " if parent_node.weigh() not in [-1, 0, 1]:\n", + " parent_node.balance(self)\n", + "\n", + " def inorder_non_recursive(self):\n", + " node = self.root\n", + " retlst = []\n", + " while node.left_child:\n", + " node = node.left_child\n", + " while node:\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " if node.right_child:\n", + " node = node.right_child\n", + " while node.left_child:\n", + " node = node.left_child\n", + " else:\n", + " while node.parent and (node == node.parent.right_child):\n", + " node = node.parent\n", + " node = node.parent\n", + " return retlst\n", + "\n", + " def preorder(self, node, retlst=None):\n", + " if retlst is None:\n", + " retlst = []\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " if node.left_child:\n", + " retlst = self.preorder(node.left_child, retlst)\n", + " if node.right_child:\n", + " retlst = self.preorder(node.right_child, retlst)\n", + " return retlst\n", + "\n", + " def inorder(self, node, retlst=None):\n", + " if retlst is None:\n", + " retlst = []\n", + " if node.left_child:\n", + " retlst = self.inorder(node.left_child, retlst)\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " if node.right_child:\n", + " retlst = self.inorder(node.right_child, retlst)\n", + " return retlst\n", + "\n", + " def postorder(self, node, retlst=None):\n", + " if retlst is None:\n", + " retlst = []\n", + " if node.left_child:\n", + " retlst = self.postorder(node.left_child, retlst)\n", + " if node.right_child:\n", + " retlst = self.postorder(node.right_child, retlst)\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " return retlst\n", + "\n", + " def as_list(self, pre_in_post):\n", + " if not self.root:\n", + " return []\n", + " if pre_in_post == 0:\n", + " return self.preorder(self.root)\n", + " elif pre_in_post == 1:\n", + " return self.inorder(self.root)\n", + " elif pre_in_post == 2:\n", + " return self.postorder(self.root)\n", + " elif pre_in_post == 3:\n", + " return self.inorder_non_recursive()\n", + "\n", + " def find(self, value, name=None):\n", + " return self.find_in_subtree(self.root, NodeKey(value, name))\n", + "\n", + " def find_in_subtree(self, node, node_key):\n", + " if node is None:\n", + " return None # key not found\n", + " if node_key < node.key:\n", + " return self.find_in_subtree(node.left_child, node_key)\n", + " elif node_key > node.key:\n", + " return self.find_in_subtree(node.right_child, node_key)\n", + " else: # key is equal to node key\n", + " return node\n", + "\n", + " def remove(self, key):\n", + " # first find\n", + " node = self.find(key)\n", + "\n", + " if not node is None:\n", + " self.element_count -= 1\n", + "\n", + " if node.is_leaf():\n", + " # The node is a leaf. Remove it and return.\n", + " self.remove_leaf(node)\n", + " elif (node.left_child is not None and node.right_child is None) or (node.left_child is None and node.right_child is not None):\n", + " # The node has only 1 child. Make the pointer to this node point to the child of this node.\n", + " self.remove_branch(node)\n", + " else:\n", + " # The node has 2 children. Swap items with the successor (the smallest item in its right subtree) and\n", + " # delete the successor from the right subtree of the node.\n", + " assert node.left_child and node.right_child\n", + " self.swap_with_successor_and_remove(node)\n", + "\n", + " def remove_leaf(self, node):\n", + " parent = node.parent\n", + " if parent:\n", + " if parent.left_child == node:\n", + " parent.left_child = None\n", + " else:\n", + " assert (parent.right_child == node)\n", + " parent.right_child = None\n", + " parent.update_height()\n", + " else:\n", + " self.root = None\n", + "\n", + " # rebalance\n", + " node = parent\n", + " while node:\n", + " if not node.weigh() in [-1, 0, 1]:\n", + " node.balance(self)\n", + " node = node.parent\n", + "\n", + " def remove_branch(self, node):\n", + " parent = node.parent\n", + " if parent:\n", + " if parent.left_child == node:\n", + " parent.left_child = node.right_child or node.left_child\n", + " else:\n", + " assert (parent.right_child == node)\n", + " parent.right_child = node.right_child or node.left_child\n", + "\n", + " if node.left_child:\n", + " node.left_child.parent = parent\n", + " else:\n", + " assert node.right_child\n", + " node.right_child.parent = parent\n", + " parent.update_height()\n", + "\n", + " # rebalance\n", + " node = parent\n", + " while node:\n", + " if not node.weigh() in [-1, 0, 1]:\n", + " node.balance(self)\n", + " node = node.parent\n", + "\n", + " def swap_with_successor_and_remove(self, node):\n", + " successor = node.right_child\n", + " while successor.left_child:\n", + " successor = successor.left_child\n", + " self.swap_nodes(node, successor)\n", + " assert (node.left_child is None)\n", + " if node.height == 0:\n", + " self.remove_leaf(node)\n", + " else:\n", + " self.remove_branch(node)\n", + "\n", + " def swap_nodes(self, node_1, node_2):\n", + " assert (node_1.height > node_2.height)\n", + " parent_1 = node_1.parent\n", + " left_child_1 = node_1.left_child\n", + " right_child_1 = node_1.right_child\n", + " parent_2 = node_2.parent\n", + " assert (not parent_2 is None)\n", + " assert (parent_2.left_child == node_2 or parent_2 == node_1)\n", + " left_child_2 = node_2.left_child\n", + " assert (left_child_2 is None)\n", + " right_child_2 = node_2.right_child\n", + "\n", + " # swap heights\n", + " tmp = node_1.height\n", + " node_1.height = node_2.height\n", + " node_2.height = tmp\n", + "\n", + " if parent_1:\n", + " if parent_1.left_child == node_1:\n", + " parent_1.left_child = node_2\n", + " else:\n", + " assert (parent_1.right_child == node_1)\n", + " parent_1.right_child = node_2\n", + " node_2.parent = parent_1\n", + " else:\n", + " self.root = node_2\n", + " node_2.parent = None\n", + "\n", + " node_2.left_child = left_child_1\n", + " left_child_1.parent = node_2\n", + " node_1.left_child = left_child_2 # None\n", + " node_1.right_child = right_child_2\n", + " if right_child_2:\n", + " right_child_2.parent = node_1\n", + " if not (parent_2 == node_1):\n", + " node_2.right_child = right_child_1\n", + " right_child_1.parent = node_2\n", + "\n", + " parent_2.left_child = node_1\n", + " node_1.parent = parent_2\n", + " else:\n", + " node_2.right_child = node_1\n", + " node_1.parent = node_2\n", + "\n", + " # use for debug only and only with small trees\n", + "\n", + " def out(self, start_node=None):\n", + " if start_node is None:\n", + " start_node = self.root\n", + "\n", + " if start_node is None:\n", + " return None\n", + " else:\n", + " return start_node.out()\n", + "\n", + "\n", + " def find_closest_to_the_left_strict(self,node_tmp,new_node_find):\n", + " if not node_tmp:\n", + " return None\n", + " if node_tmp.key >= new_node_find:\n", + " left_node_result = self.find_closest_to_the_left_strict(node_tmp.left_child,new_node_find)\n", + " if left_node_result:\n", + " return left_node_result\n", + " else:\n", + " return None\n", + " else:\n", + " right_node_result = self.find_closest_to_the_left_strict(node_tmp.right_child,new_node_find)\n", + " if right_node_result:\n", + " return right_node_result\n", + " else:\n", + " return node_tmp\n", + "\n", + " def find_closest_to_the_left_strict_value_only(self,value):\n", + " return self.find_closest_to_the_left_strict(self.root,NodeKey(value))\n", + "\n", + " def find_closest_to_the_right_strict(self,node_tmp,new_node_find):\n", + " if not node_tmp:\n", + " return None\n", + " if node_tmp.key > new_node_find:\n", + " left_node_result = self.find_closest_to_the_right_strict(node_tmp.left_child,new_node_find)\n", + " if left_node_result:\n", + " return left_node_result\n", + " else:\n", + " return node_tmp\n", + " else:\n", + " right_node_result = self.find_closest_to_the_right_strict(node_tmp.right_child,new_node_find)\n", + " if right_node_result:\n", + " return right_node_result\n", + " else:\n", + " return None\n", + "\n", + " def find_closest_to_the_right_strict_value_only(self,value):\n", + " return self.find_closest_to_the_right_strict(self.root,NodeKey(value))\n", + "\n", + "\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# redo Q1" + ] + }, + { + "cell_type": "code", + "execution_count": 501, + "metadata": {}, + "outputs": [], + "source": [ + "list_now = [423,231,5134,21332]" + ] + }, + { + "cell_type": "code", + "execution_count": 502, + "metadata": {}, + "outputs": [], + "source": [ + "heapq.heapify(list_now)" + ] + }, + { + "cell_type": "code", + "execution_count": 503, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[231, 423, 5134, 21332]" + ] + }, + "execution_count": 503, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list_now" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 499, + "metadata": {}, + "outputs": [], + "source": [ + "#!/bin/python\n", + "\n", + "import math\n", + "import os\n", + "import random\n", + "import re\n", + "import sys\n", + "\n", + "import heapq" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 550, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n", + "09:30:00 1 b 100 l 9.99\n", + "09:31:00 2 b 1000 l 9.95\n", + "09:32:00 3 s 100 l 10.01\n", + "09:33:00 4 s 1000 l 10.05\n", + "09:41:00 5 b 200 m -1.00\n" + ] + } + ], + "source": [ + "input_1 = raw_input()\n", + "input_1 = int(input_1)\n", + "list_of_lines = []\n", + "for i in range(input_1):\n", + " input_2 = raw_input()\n", + " list_of_lines.append(input_2)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 583, + "metadata": {}, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:42:00 6 s 200 m -1.00\")" + ] + }, + { + "cell_type": "code", + "execution_count": 594, + "metadata": {}, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:43:00 7 b 200 l 11\")" + ] + }, + { + "cell_type": "code", + "execution_count": 608, + "metadata": {}, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:44:00 8 s 200 m -1\")" + ] + }, + { + "cell_type": "code", + "execution_count": 621, + "metadata": {}, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:45:00 8 s 1000 m -1\")" + ] + }, + { + "cell_type": "code", + "execution_count": 640, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "list_of_lines.append(\"09:45:00 8 s 500 l 25\")" + ] + }, + { + "cell_type": "code", + "execution_count": 641, + "metadata": {}, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:45:00 8 b 800 l 25\")" + ] + }, + { + "cell_type": "code", + "execution_count": 646, + "metadata": {}, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:46:00 9 b 100 l 35\")" + ] + }, + { + "cell_type": "code", + "execution_count": 649, + "metadata": {}, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:47:00 10 b 700 l 35\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 650, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['09:30:00 1 b 100 l 9.99',\n", + " '09:31:00 2 b 1000 l 9.95',\n", + " '09:32:00 3 s 100 l 10.01',\n", + " '09:33:00 4 s 1000 l 10.05',\n", + " '09:41:00 5 b 200 m -1.00',\n", + " '09:42:00 6 s 200 m -1.00',\n", + " '09:43:00 7 b 200 l 11',\n", + " '09:44:00 8 s 200 m -1',\n", + " '09:45:00 8 s 1000 m -1',\n", + " '09:45:00 8 s 500 l 25',\n", + " '09:45:00 8 b 800 l 25',\n", + " '09:46:00 9 b 100 l 35',\n", + " '09:47:00 10 b 700 l 35']" + ] + }, + "execution_count": 650, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list_of_lines" + ] + }, + { + "cell_type": "code", + "execution_count": 639, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'09:45:00 8 s 1000 l 700'" + ] + }, + "execution_count": 639, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list_of_lines.pop()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 651, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "09:41:00 5 3 10.01 100\n", + "09:41:00 5 4 10.05 100\n", + "09:42:00 6 1 9.99 100\n", + "09:42:00 6 2 9.95 100\n", + "09:43:00 7 4 10.05 200\n", + "09:44:00 8 2 9.95 200\n", + "09:45:00 8 2 9.95 700\n", + "09:45:00 8 4 10.05 700\n", + "09:45:00 8 8 25.00 100\n", + "09:46:00 9 8 25.00 100\n", + "09:47:00 10 8 25.00 300\n" + ] + } + ], + "source": [ + "\"\"\"ask heap is min heap (standard) containing (price,id,amount) \n", + "and bid heap is max heap but implemented with min heap where each element is\n", + "(-price,id,amount) \"\"\"\n", + "string_to_print = \"\"\n", + "bid_heap = []\n", + "ask_heap = []\n", + "\n", + "for i in range(len(list_of_lines)):\n", + " \n", + " line_now = list_of_lines[i]\n", + " splited_line = line_now.split(\" \")\n", + " time_stamp = splited_line[0]\n", + " id_now = int(splited_line[1])\n", + " buy_or_sell = splited_line[2]\n", + " amount = int(splited_line[3])\n", + " limit_or_market = splited_line[4]\n", + " limit_price = float(splited_line[5])\n", + "\n", + " limit_or_market_original = limit_or_market\n", + "\n", + " if limit_or_market == \"m\":\n", + " \"\"\"if it is market order, just consider it as a limit order with infinite\n", + " limit price for buy and 0 limit price for sell\"\"\"\n", + " limit_or_market = \"l\"\n", + " if buy_or_sell == \"b\":\n", + " limit_price = float(\"infinity\")\n", + " if buy_or_sell == \"s\":\n", + " limit_price = 0 \n", + "\n", + "\n", + " if limit_or_market == \"l\":\n", + " if buy_or_sell == \"b\":\n", + " \"\"\"look into btree_ask\"\"\"\n", + " order_remaining = amount\n", + " \"\"\"firstly see if any amount can be filled \"\"\"\n", + " price_now = None\n", + " if len(ask_heap)>0:\n", + " if ask_heap[0][0] <= limit_price:\n", + " price_now = ask_heap[0][0]\n", + " \n", + " while price_now != None and len(ask_heap)>0 and order_remaining>0:\n", + " _, id_in_the_book, amount_in_the_book = ask_heap[0]\n", + " amount_filled = min(order_remaining,amount_in_the_book)\n", + " order_remaining = order_remaining - amount_filled\n", + " string_tmp = time_stamp + \" \" + str(id_now) + \" \" + str(id_in_the_book) + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " print string_tmp\n", + " if amount_filled == amount_in_the_book:\n", + " heapq.heappop(ask_heap)\n", + " else:\n", + " ask_heap[0] = (price_now, id_in_the_book, amount_in_the_book - amount_filled)\n", + " price_now = None\n", + " if len(ask_heap)>0:\n", + " if ask_heap[0][0] <= limit_price:\n", + " price_now = ask_heap[0][0]\n", + "\n", + " \"\"\"post buy order in bid_heap\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + " heapq.heappush(bid_heap,(-limit_price,id_now,order_remaining))\n", + " \n", + " if buy_or_sell == \"s\":\n", + " \"\"\"look into btree_ask\"\"\"\n", + " order_remaining = amount\n", + " \"\"\"firstly see if any amount can be filled \"\"\"\n", + " price_now = None\n", + " if len(bid_heap)>0:\n", + " if -bid_heap[0][0] >= limit_price: #-bid_heap[0] is the price, so that bid the top pops out\n", + " price_now = -bid_heap[0][0]\n", + "\n", + "\n", + " while price_now != None and len(bid_heap)>0 and order_remaining>0: \n", + " _, id_in_the_book, amount_in_the_book = bid_heap[0]\n", + " amount_filled = min(order_remaining,amount_in_the_book)\n", + " order_remaining = order_remaining - amount_filled\n", + " string_tmp = time_stamp + \" \" + str(id_now) + \" \" + str(id_in_the_book) + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " print string_tmp\n", + " if amount_filled == amount_in_the_book:\n", + " heapq.heappop(bid_heap)\n", + " else:\n", + " bid_heap[0] = (-price_now, id_in_the_book, amount_in_the_book - amount_filled)\n", + " price_now = None\n", + " if len(bid_heap)>0:\n", + " if -bid_heap[0][0] >= limit_price: #-bid_heap[0] is the price, so that bid the top pops out\n", + " price_now = -bid_heap[0][0]\n", + "\n", + "\n", + " \"\"\"post sell order in ask_heap\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + " heapq.heappush(ask_heap,(limit_price,id_now,order_remaining))\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 652, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[(-35.0, 10, 400)]\n", + "[]\n" + ] + } + ], + "source": [ + " print bid_heap\n", + " print ask_heap\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 615, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 615, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(bid_heap)>0" + ] + }, + { + "cell_type": "code", + "execution_count": 616, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-9.95" + ] + }, + "execution_count": 616, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "-bid_heap[0][0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 613, + "metadata": {}, + "outputs": [ + { + "ename": "IndentationError", + "evalue": "expected an indented block (, line 2)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m \u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m expected an indented block\n" + ] + } + ], + "source": [ + " if len(bid_heap)>0:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 605, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(9.95, 2, 900)]" + ] + }, + "execution_count": 605, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bid_heap" + ] + }, + { + "cell_type": "code", + "execution_count": 606, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(10.05, 4, 700)]" + ] + }, + "execution_count": 606, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ask_heap" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 563, + "metadata": {}, + "outputs": [ + { + "ename": "TypeError", + "evalue": "float argument required, not NoneType", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mtime_stamp\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mid_now\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mid_in_the_book\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m\"%.2f\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0mprice_now\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mamount_filled\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mTypeError\u001b[0m: float argument required, not NoneType" + ] + } + ], + "source": [ + "time_stamp + \" \" + str(id_now) + \" \" + str(id_in_the_book) + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 513, + "metadata": {}, + "outputs": [ + { + "ename": "TypeError", + "evalue": "cannot concatenate 'str' and 'int' objects", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mtime_stamp\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mid_now\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mid_in_the_book\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m\"%.2f\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0mprice_now\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mamount_filled\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m: cannot concatenate 'str' and 'int' objects" + ] + } + ], + "source": [ + " time_stamp + \" \" + str(id_now) + \" \" + id_in_the_book + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled)" + ] + }, + { + "cell_type": "code", + "execution_count": 509, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10.01" + ] + }, + "execution_count": 509, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "limit_price" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# final product" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#!/bin/python\n", + "\n", + "import math\n", + "import os\n", + "import random\n", + "import re\n", + "import sys\n", + "import heapq\n", + "\n", + "input_1 = raw_input()\n", + "input_1 = int(input_1)\n", + "list_of_lines = []\n", + "for i in range(input_1):\n", + " input_2 = raw_input()\n", + " list_of_lines.append(input_2)\n", + "\n", + "\n", + "\"\"\"ask heap is min heap (standard) containing (price,id,amount) \n", + "and bid heap is max heap but implemented with min heap where each element is\n", + "(-price,id,amount) \"\"\"\n", + "string_to_print = \"\"\n", + "bid_heap = []\n", + "ask_heap = []\n", + "\n", + "for i in range(len(list_of_lines)):\n", + " \n", + " line_now = list_of_lines[i]\n", + " splited_line = line_now.split(\" \")\n", + " time_stamp = splited_line[0]\n", + " id_now = int(splited_line[1])\n", + " buy_or_sell = splited_line[2]\n", + " amount = int(splited_line[3])\n", + " limit_or_market = splited_line[4]\n", + " limit_price = float(splited_line[5])\n", + "\n", + " limit_or_market_original = limit_or_market\n", + "\n", + " if limit_or_market == \"m\":\n", + " \"\"\"if it is market order, just consider it as a limit order with infinite\n", + " limit price for buy and 0 limit price for sell\"\"\"\n", + " limit_or_market = \"l\"\n", + " if buy_or_sell == \"b\":\n", + " limit_price = float(\"infinity\")\n", + " if buy_or_sell == \"s\":\n", + " limit_price = 0 \n", + "\n", + "\n", + " if limit_or_market == \"l\":\n", + " if buy_or_sell == \"b\":\n", + " \"\"\"look into btree_ask\"\"\"\n", + " order_remaining = amount\n", + " \"\"\"firstly see if any amount can be filled \"\"\"\n", + " price_now = None\n", + " if len(ask_heap)>0:\n", + " if ask_heap[0][0] <= limit_price:\n", + " price_now = ask_heap[0][0]\n", + " \n", + " while price_now != None and len(ask_heap)>0 and order_remaining>0:\n", + " _, id_in_the_book, amount_in_the_book = ask_heap[0]\n", + " amount_filled = min(order_remaining,amount_in_the_book)\n", + " order_remaining = order_remaining - amount_filled\n", + " string_tmp = time_stamp + \" \" + str(id_now) + \" \" + str(id_in_the_book) + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " print string_tmp\n", + " if amount_filled == amount_in_the_book:\n", + " heapq.heappop(ask_heap)\n", + " else:\n", + " ask_heap[0] = (price_now, id_in_the_book, amount_in_the_book - amount_filled)\n", + " price_now = None\n", + " if len(ask_heap)>0:\n", + " if ask_heap[0][0] <= limit_price:\n", + " price_now = ask_heap[0][0]\n", + "\n", + " \"\"\"post buy order in bid_heap\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + " heapq.heappush(bid_heap,(-limit_price,id_now,order_remaining))\n", + " \n", + " if buy_or_sell == \"s\":\n", + " \"\"\"look into btree_ask\"\"\"\n", + " order_remaining = amount\n", + " \"\"\"firstly see if any amount can be filled \"\"\"\n", + " price_now = None\n", + " if len(bid_heap)>0:\n", + " if -bid_heap[0][0] >= limit_price: #-bid_heap[0] is the price, so that bid the top pops out\n", + " price_now = -bid_heap[0][0]\n", + "\n", + "\n", + " while price_now != None and len(bid_heap)>0 and order_remaining>0: \n", + " _, id_in_the_book, amount_in_the_book = bid_heap[0]\n", + " amount_filled = min(order_remaining,amount_in_the_book)\n", + " order_remaining = order_remaining - amount_filled\n", + " string_tmp = time_stamp + \" \" + str(id_now) + \" \" + str(id_in_the_book) + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " print string_tmp\n", + " if amount_filled == amount_in_the_book:\n", + " heapq.heappop(bid_heap)\n", + " else:\n", + " bid_heap[0] = (-price_now, id_in_the_book, amount_in_the_book - amount_filled)\n", + " price_now = None\n", + " if len(bid_heap)>0:\n", + " if -bid_heap[0][0] >= limit_price: #-bid_heap[0] is the price, so that bid the top pops out\n", + " price_now = -bid_heap[0][0]\n", + "\n", + "\n", + " \"\"\"post sell order in ask_heap\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + " heapq.heappush(ask_heap,(limit_price,id_now,order_remaining))\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# real Q1\n" + ] + }, + { + "cell_type": "code", + "execution_count": 483, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "import heapq" + ] + }, + { + "cell_type": "code", + "execution_count": 490, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "list_now = [1,3,2,4,2,13,1]" + ] + }, + { + "cell_type": "code", + "execution_count": 493, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "heapq.heapify(list_now)" + ] + }, + { + "cell_type": "code", + "execution_count": 494, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 2, 1, 4, 3, 13, 2]" + ] + }, + "execution_count": 494, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list_now" + ] + }, + { + "cell_type": "code", + "execution_count": 496, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "heapq.heappush(list_now,10)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 481, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n", + "09:30:00 1 b 100 l 9.99\n", + "09:31:00 2 b 1000 l 9.95\n", + "09:32:00 3 s 100 l 10.01\n", + "09:33:00 4 s 1000 l 10.05\n", + "09:41:00 5 b 200 m -1.00\n" + ] + } + ], + "source": [ + " input_1 = raw_input()\n", + " input_1 = int(input_1)\n", + " list_of_lines = []\n", + " for i in range(input_1):\n", + " input_2 = raw_input()\n", + " list_of_lines.append(input_2)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "string_to_print = \"\"\n", + "\n", + "\"\"\"this hash table is used to associate with each bid/ask with its avaialble offer in sequence\n", + "we will use queue here, an implemention from python is with deque(a bit more expensive)\n", + "\"\"\"\n", + "\"\"\"I realized there is issue in my binary search tree code. I cannot Tree.find after I Tree.search\"\"\"\n", + "\"\"\"i don't know of other built in binary search in python and I don't have time to rebuilt \n", + "my previous binary tree , so I have to use a less efficient method with sorted list\"\"\"\n", + "bid_hash = {}\n", + "ask_hash = {}\n", + "btree_bid = BinaryTree()\n", + "btree_ask = BinaryTree()\n", + "sorted_list_bid = []\n", + "sorted_list_ask = []" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 482, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "here\n", + "here\n" + ] + }, + { + "ename": "KeyError", + "evalue": "9.99", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 123\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0mprice_now\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0morder_remaining\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 124\u001b[0;31m \u001b[0mbid_hash_value_deque_now\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mask_hash\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mprice_now\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 125\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbid_hash_value_deque_now\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;36m0\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0morder_remaining\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 126\u001b[0m \u001b[0mthe_id_amount_to_examine\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mbid_hash_value_deque_now\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: 9.99" + ] + } + ], + "source": [ + "for i in range(input_1):\n", + " line_now = list_of_lines[i]\n", + " splited_line = line_now.split(\" \")\n", + "\n", + " time_stamp = splited_line[0]\n", + " id_now = splited_line[1]\n", + " buy_or_sell = splited_line[2]\n", + " amount = int(splited_line[3])\n", + " limit_or_market = splited_line[4]\n", + " limit_price = float(splited_line[5])\n", + "\n", + " limit_or_market_original = limit_or_market\n", + "\n", + " if limit_or_market == \"m\":\n", + " \"\"\"if it is market order, just consider it as a limit order with 0\n", + " limit price for buy and infinite limit price for sell\"\"\"\n", + " limit_or_market = \"l\"\n", + " if buy_or_sell == \"b\":\n", + " limit_price = 0\n", + " if buy_or_sell == \"s\":\n", + " limit_price = float(\"infinity\")\n", + "\n", + "\n", + "\n", + " if limit_or_market == \"l\":\n", + " if buy_or_sell == \"b\":\n", + " print \"here\"\n", + " \"\"\"look into btree_ask\"\"\"\n", + " order_remaining = amount\n", + " \"\"\"firstly see if any amount can be filled \"\"\"\n", + " price_now = None\n", + " lo, matched = bisect_left(sorted_list_ask,limit_price)\n", + " if matched:\n", + " price_now = sorted_list_bid[lo]\n", + " elif lo+1 < len(sorted_list_ask):\n", + " price_now = sorted_list_ask[lo + 1]\n", + " \n", + "# if btree_ask.find(limit_price):\n", + "# price_now = limit_price\n", + "# else:\n", + "# node_now = btree_ask.find_closest_to_the_right_strict_value_only(limit_price)\n", + "# if node_now:\n", + "# price_now = node_now.value\n", + "\n", + " while price_now != None and order_remaining>0:\n", + " ask_hash_value_deque_now = ask_hash[price_now]\n", + " while len(ask_hash_value_deque_now)>0 and order_remaining>0:\n", + " the_id_amount_to_examine = ask_hash_value_deque_now[0]\n", + " id_in_the_book = the_id_amount_to_examine[0]\n", + " amount_in_the_book = the_id_amount_to_examine[1]\n", + " amount_filled = min(order_remaining,amount_in_the_book)\n", + " order_remaining = order_remaining - amount_filled\n", + " string_tmp = time_stamp + \" \" + id_now + \" \" + id_in_the_book + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " string_to_print += string_tmp\n", + " print string_tmp\n", + " if amount_filled == amount_in_the_book:\n", + " ask_hash_value_deque_now.popleft()\n", + " if len(ask_hash_value_deque_now) == 0 :\n", + " del ask_hash[price_now]\n", + "# btree_ask.remove(price_now)\n", + " lo, matched = bisect_left(sorted_list_ask,limit_price)\n", + " sorted_list_ask.remove(lo)\n", + " else:\n", + " ask_hash_value_deque_now[0][1] = amount_in_the_book - amount_filled\n", + " price_now = None\n", + " lo, matched = bisect_left(sorted_list_ask,limit_price)\n", + " if matched:\n", + " price_now = sorted_list_bid[lo]\n", + " elif lo+1 < len(sorted_list_ask):\n", + " price_now = sorted_list_ask[lo + 1]\n", + "\n", + "# node_now = btree_ask.find_closest_to_the_right_strict_value_only(limit_price)\n", + "# if node_now:\n", + "# price_now = node_now.value\n", + "\n", + "\n", + " \"\"\"post buy order in btree_bid\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + " \"\"\"tree is more efficient\"\"\"\n", + "# btree_bid.insert(limit_price)\n", + " insort_left(sorted_list_bid,limit_price)\n", + " if limit_price in bid_hash:\n", + " bid_hash[limit_price].append([id_now,order_remaining])\n", + " else:\n", + " bid_hash[limit_price] = deque()\n", + " bid_hash[limit_price].append([id_now,order_remaining]) \n", + "\n", + " if buy_or_sell == \"s\":\n", + " order_remaining = amount\n", + " price_now = None\n", + " lo, matched = bisect_left(sorted_list_bid,limit_price)\n", + " if matched:\n", + " price_now = sorted_list_bid[lo]\n", + " elif lo -1 >= 0:\n", + " price_now = sorted_list_bid[lo-1]\n", + "\n", + " \n", + "# if btree_bid.find(limit_price):\n", + "# price_now = limit_price\n", + "# else:\n", + "# node_now = btree_bid.find_closest_to_the_left_strict_value_only(limit_price)\n", + "# if node_now:\n", + "# price_now = node_now.value\n", + "\n", + " while price_now != None and order_remaining>0:\n", + " bid_hash_value_deque_now = ask_hash[price_now]\n", + " while len(bid_hash_value_deque_now)>0 and order_remaining>0:\n", + " the_id_amount_to_examine = bid_hash_value_deque_now[0]\n", + " id_in_the_book = the_id_amount_to_examine[0]\n", + " amount_in_the_book = the_id_amount_to_examine[1]\n", + " amount_filled = min(order_remaining,amount_in_the_book)\n", + " order_remaining = order_remaining - amount_filled\n", + " string_tmp = time_stamp + \" \" + id_now + \" \" + id_in_the_book + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " string_to_print += string_tmp\n", + " print string_tmp\n", + " if amount_filled == amount_in_the_book:\n", + " bid_hash_value_deque_now.popleft()\n", + " if len(bid_hash_value_deque_now) == 0 :\n", + " del bid_hash[price_now]\n", + " \"\"\"this is designed to work, but due to some issue, it does not work for now, I will need more time to debug into it \"\"\"\n", + "# btree_bid.remove(price_now)\n", + " lo, matched = bisect_left(sorted_list_bid,limit_price)\n", + " sorted_list_bid.remove(lo)\n", + " else:\n", + " ask_hash_value_deque_now[0][1] = amount_in_the_book - amount_filled\n", + " price_now = None\n", + " lo, matched = bisect_left(sorted_list_bid,limit_price)\n", + " if matched:\n", + " price_now = sorted_list_bid[lo]\n", + " elif lo -1 >= 0:\n", + " price_now = sorted_list_bid[lo-1]\n", + "\n", + " \"\"\"below is more efficient but there is bug\"\"\"\n", + "# node_now = btree_bid.find_closest_to_the_left_strict_value_only(limit_price)\n", + "# if node_now:\n", + "# price_now = node_now.value\n", + "\n", + " \n", + " \n", + " \"\"\"post sell order in btree_ask\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + "# print \"inserting \"+str(limit_price)\n", + " insort_left(sorted_list_ask,limit_price)\n", + "# btree_ask.insert(limit_price)\n", + " if limit_price in ask_hash:\n", + " ask_hash[limit_price].append([id_now,order_remaining])\n", + " else:\n", + " ask_hash[limit_price] = deque()\n", + " ask_hash[limit_price].append([id_now,order_remaining]) " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 336, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree = BinaryTree()" + ] + }, + { + "cell_type": "code", + "execution_count": 347, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "for i in range(1000):\n", + " rand_now = random.randint(0,100)\n", + "\n", + " btree.insert(rand_now)\n", + "btree.insert(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 348, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]\n" + ] + } + ], + "source": [ + "print btree.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 349, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.Node instance at 0x7fabdefd10e0>" + ] + }, + "execution_count": 349, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree.find(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 350, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree.remove(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 351, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree.find(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 352, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]\n" + ] + } + ], + "source": [ + "print btree.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 353, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + " btree.insert(11.1)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 354, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11.1, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]\n" + ] + } + ], + "source": [ + "print btree.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 355, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree.remove(11.1)" + ] + }, + { + "cell_type": "code", + "execution_count": 356, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]\n" + ] + } + ], + "source": [ + "print btree.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 357, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[10.01, 10.05]" + ] + }, + "execution_count": 357, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 358, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.Node instance at 0x7fabec0245a8>" + ] + }, + "execution_count": 358, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.find(10.01)" + ] + }, + { + "cell_type": "code", + "execution_count": 359, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree_ask.remove(10.01)" + ] + }, + { + "cell_type": "code", + "execution_count": 360, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.Node instance at 0x7fabec0245a8>" + ] + }, + "execution_count": 360, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.find(10.01)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 335, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[10.01, 10.05]" + ] + }, + "execution_count": 335, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 317, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{10.05: deque([['4', 1000]])}" + ] + }, + "execution_count": 317, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ask_hash" + ] + }, + { + "cell_type": "code", + "execution_count": 313, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "10.01" + ] + }, + "execution_count": 313, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "price_now" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 290, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "i = i + 1" + ] + }, + { + "cell_type": "code", + "execution_count": 291, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "\n", + "line_now = list_of_lines[i]\n", + "splited_line = line_now.split(\" \")\n", + "\n", + "time_stamp = splited_line[0]\n", + "id_now = splited_line[1]\n", + "buy_or_sell = splited_line[2]\n", + "amount = int(splited_line[3])\n", + "limit_or_market = splited_line[4]\n", + "limit_price = float(splited_line[5])\n", + "\n", + "limit_or_market_original = limit_or_market\n", + "\n", + "if limit_or_market == \"m\":\n", + " \"\"\"if it is market order, just consider it as a limit order with 0\n", + " limit price for buy and infinite limit price for sell\"\"\"\n", + " limit_or_market = \"l\"\n", + " if buy_or_sell == \"b\":\n", + " limit_price = 0\n", + " if buy_or_sell == \"s\":\n", + " limit_price = float(\"infinity\")\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 292, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "here\n" + ] + } + ], + "source": [ + " if limit_or_market == \"l\":\n", + " if buy_or_sell == \"b\":\n", + " print \"here\"\n", + " \"\"\"look into btree_ask\"\"\"\n", + " order_remaining = amount\n", + " \"\"\"firstly see if any amount can be filled \"\"\"\n", + " # condition_that_the_order_cannot_be_filled_at_all = btree_ask.find(limit_price) == None and btree_ask.find_closest_to_the_right_strict_value_only(limit_price) == None: \n", + " # node_for_limit_price = btree_ask.find(limit_price)\n", + " # if node_for_limit_price:\n", + " price_now = None\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 293, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + " if btree_ask.find(limit_price):\n", + " price_now = limit_price\n", + " else:\n", + " node_now = btree_ask.find_closest_to_the_right_strict_value_only(limit_price)\n", + " if node_now:\n", + " price_now = node_now.value\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 294, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "10.01" + ] + }, + "execution_count": 294, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "price_now" + ] + }, + { + "cell_type": "code", + "execution_count": 295, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 295, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "price_now != None and order_remaining>0" + ] + }, + { + "cell_type": "code", + "execution_count": 296, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "ask_hash_value_deque_now = ask_hash[price_now]\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 297, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "deque([['3', 100]])" + ] + }, + "execution_count": 297, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ask_hash_value_deque_now" + ] + }, + { + "cell_type": "code", + "execution_count": 298, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "09:41:00 5 3 10.01 100\n" + ] + } + ], + "source": [ + "the_id_amount_to_examine = ask_hash_value_deque_now[0]\n", + "id_in_the_book = the_id_amount_to_examine[0]\n", + "amount_in_the_book = the_id_amount_to_examine[1]\n", + "amount_filled = min(order_remaining,amount_in_the_book)\n", + "order_remaining = order_remaining - amount_filled\n", + "string_tmp = time_stamp + \" \" + id_now + \" \" + id_in_the_book + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + "string_to_print += string_tmp\n", + "print string_tmp\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 262, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree_ask.find(limit_price)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 265, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{9.95: deque([['2', 1000]]), 9.99: deque([['1', 100]])}" + ] + }, + "execution_count": 265, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bid_hash" + ] + }, + { + "cell_type": "code", + "execution_count": 266, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[9.95, 9.99]" + ] + }, + "execution_count": 266, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_bid.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 267, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{10.01: deque([['3', 100]]), 10.05: deque([['4', 1000]])}" + ] + }, + "execution_count": 267, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ask_hash" + ] + }, + { + "cell_type": "code", + "execution_count": 268, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[10.01, 10.05]" + ] + }, + "execution_count": 268, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# debug history" + ] + }, + { + "cell_type": "code", + "execution_count": 265, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{9.95: deque([['2', 1000]]), 9.99: deque([['1', 100]])}" + ] + }, + "execution_count": 265, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bid_hash" + ] + }, + { + "cell_type": "code", + "execution_count": 266, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[9.95, 9.99]" + ] + }, + "execution_count": 266, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_bid.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 267, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{10.01: deque([['3', 100]]), 10.05: deque([['4', 1000]])}" + ] + }, + "execution_count": 267, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ask_hash" + ] + }, + { + "cell_type": "code", + "execution_count": 268, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[10.01, 10.05]" + ] + }, + "execution_count": 268, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 206, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "splited_line = line_now.split(\" \")" + ] + }, + { + "cell_type": "code", + "execution_count": 207, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "time_stamp = splited_line[0]\n", + "id_now = splited_line[1]\n", + "buy_or_sell = splited_line[2]\n", + "amount = int(splited_line[3])\n", + "limit_or_market = splited_line[4]\n", + "limit_price = float(splited_line[5])" + ] + }, + { + "cell_type": "code", + "execution_count": 208, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "limit_or_market_original = limit_or_market" + ] + }, + { + "cell_type": "code", + "execution_count": 215, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "if limit_or_market == \"m\":\n", + " \"\"\"if it is market order, just consider it as a limit order with 0\n", + " limit price for buy and infinite limit price for sell\"\"\"\n", + " limit_or_market = \"l\"\n", + " if buy_or_sell == \"b\":\n", + " limit_price = 0\n", + " if buy_or_sell == \"s\":\n", + " limit_price = float(\"infinity\")\n", + "\n", + "\n", + "\n", + "if limit_or_market == \"l\":\n", + " if buy_or_sell == \"b\":\n", + " print \"here\"\n", + " \"\"\"look into btree_ask\"\"\"\n", + " order_remaining = amount\n", + " \"\"\"firstly see if any amount can be filled \"\"\"\n", + "# condition_that_the_order_cannot_be_filled_at_all = btree_ask.find(limit_price) == None and btree_ask.find_closest_to_the_right_strict_value_only(limit_price) == None: \n", + "# node_for_limit_price = btree_ask.find(limit_price)\n", + "# if node_for_limit_price:\n", + " price_now = None\n", + " if btree_ask.find(limit_price):\n", + " price_now = limit_price\n", + " else:\n", + " node_now = btree_ask.find_closest_to_the_right_strict_value_only(limit_price)\n", + " if node_now:\n", + " price_now = node_now.value\n", + "\n", + " while price_now != None and order_remaining>0:\n", + " bid_hash_value_deque_now = bid_hash[limit_price]\n", + " while len(bid_hash_value_deque_now)>0 and order_remaining>0:\n", + " the_id_amount_to_examine = bid_hash_value_deque_now[0]\n", + " id_in_the_book = the_id_amount_to_examine[0]\n", + " amount_in_the_book = the_id_amount_to_examine[1]\n", + " amount_filled = min(order_remaining,amount_in_the_book)\n", + " order_remaining = order_remaining - amount_filled\n", + " string_tmp = time_stamp + \" \" + id_now + \" \" + id_in_the_book + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " string_to_print += string_tmp\n", + " print string_tmp\n", + " if amount_filled == amount_in_the_book:\n", + " bid_hash_value_deque_now.deque_tmp.popleft()\n", + " if len(bid_hash_value_deque_now) == 0 :\n", + " btree_ask.remove(price_now)\n", + " ask_hash.remove(price_now)\n", + " else:\n", + " bid_hash_value_deque_now[0][1] = amount_in_the_book - amount_filled\n", + " price_now = None\n", + " if btree_ask.find(limit_price):\n", + " price_now = limit_price\n", + " else:\n", + " price_now = btree_ask.find_closest_to_the_right_strict_value_only(limit_price).value\n", + " \n", + " \"\"\"post buy order in btree_bid\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + " btree_bid.insert(limit_price)\n", + " if limit_price in bid_hash:\n", + " bid_hash[limit_price].append([id_now,order_remaining])\n", + " else:\n", + " bid_hash[limit_price] = deque()\n", + " bid_hash[limit_price].append([id_now,order_remaining]) \n", + " \n", + " \n", + " \n", + " if buy_or_sell == \"s\":\n", + " order_remaining = amount\n", + "\n", + " \n", + " \"\"\"post sell order in btree_ask\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + " btree_ask.insert(limit_price)\n", + " if limit_price in bid_hash:\n", + " ask_hash[limit_price].append([id_now,order_remaining])\n", + " else:\n", + " ask_hash[limit_price] = deque()\n", + " ask_hash[limit_price].append([id_now,order_remaining]) \n", + "\n", + " \n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 178, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[9.99, 100.0]" + ] + }, + "execution_count": 178, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_bid.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 179, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{9.99: deque([['1', 100.0], ['1', 100.0]])}" + ] + }, + "execution_count": 179, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bid_hash" + ] + }, + { + "cell_type": "code", + "execution_count": 158, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 158, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 159, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree_ask.insert(2)" + ] + }, + { + "cell_type": "code", + "execution_count": 163, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "node_now = btree_ask.find_closest_to_the_right_strict_value_only(1.99).value" + ] + }, + { + "cell_type": "code", + "execution_count": 164, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 164, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_now.value" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 100, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.root == None" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + " \"\"\"post buy order in btree_bid\"\"\" \n", + " \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree_bid.insert(limit_price)\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 118, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "if limit_price in bid_hash:\n", + " bid_hash[limit_price].append([id_now,order_remaining])\n", + "else:\n", + " bid_hash[limit_price] = deque()\n", + " bid_hash[limit_price].append([id_now,order_remaining])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 129, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "deque_tmp = deque()" + ] + }, + { + "cell_type": "code", + "execution_count": 130, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "deque_tmp.append([id_now,order_remaining])" + ] + }, + { + "cell_type": "code", + "execution_count": 131, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "deque_tmp[0][1] = 20" + ] + }, + { + "cell_type": "code", + "execution_count": 132, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "deque([['1', 20]])" + ] + }, + "execution_count": 132, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "deque_tmp" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n" + ] + } + ], + "source": [ + "if btree_ask.find(limit_price) == None:\n", + " print 2" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "100.0" + ] + }, + "execution_count": 116, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "order_remaining" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n" + ] + } + ], + "source": [ + "if btree_ask.find_closest_to_the_right_strict_value_only(limit_price) == None:\n", + " print 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + " if btree_ask.root == None:\n", + " to_fill_bid_book = True\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree_ask" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree_ask.fi" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "if limit_or_market == \"m\":\n", + " pass" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree_now.insert()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "input_1" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'09:41:00 5 b 200 m -1.00'" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "input_2" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['09:41:00', '5', 'b', '200', 'm', '-1.00']" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "input_2.split(\" \")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# Q1" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "#!/bin/python\n", + "\n", + "import math\n", + "import os\n", + "import random\n", + "import re\n", + "import sys\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# fptr = open(os.environ['OUTPUT_PATH'], 'w')\n", + "\n", + "arr_count = int(raw_input().strip())\n", + "\n", + "arr = []\n", + "\n", + "for _ in xrange(arr_count):\n", + " arr_item = int(raw_input().strip())\n", + " arr.append(arr_item)\n", + "\n", + "k = int(raw_input().strip())" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n", + "2\n", + "3\n", + "1\n", + "5\n" + ] + }, + { + "ename": "NameError", + "evalue": "name 'findNumber' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mk\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mraw_input\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstrip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 13\u001b[0;31m \u001b[0mres\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfindNumber\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mk\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 14\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0mfptr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m'\\n'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'findNumber' is not defined" + ] + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "if k in arr:\n", + " print \"YES\"" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def findNumber(arr, k):\n", + " if k in arr:\n", + " print \"YES\"\n", + " return \"YES\"\n", + " else:\n", + " print \"NO\"\n", + " return \"NO\"" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[2, 3, 1]" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "arr" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "k" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "NO\n" + ] + } + ], + "source": [ + "res = findNumber(arr, k)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "fptr.write(res + '\\n')\n", + "\n", + "fptr.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# Q2" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n", + "9\n" + ] + } + ], + "source": [ + " l = int(raw_input().strip())\n", + "\n", + " r = int(raw_input().strip())\n" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def oddNumbers(l, r):\n", + " if l%2 == 1 :\n", + " #i is odd\n", + " array = range(l,r+1,2)\n", + " else:\n", + " array = range(l+1,r+1,2)\n", + "\n", + "\n", + " return array" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "initial = i" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[3, 5, 7, 9]" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "array" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[3, 5, 7, 9]" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "l%2" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "8\n" + ] + } + ], + "source": [ + "for i in range(3,9):\n", + " print i" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "i%2 == 0 " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "l" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "9" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "r" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/.ipynb_checkpoints/Untitled2-checkpoint.ipynb b/.ipynb_checkpoints/Untitled2-checkpoint.ipynb new file mode 100644 index 00000000..292dc697 --- /dev/null +++ b/.ipynb_checkpoints/Untitled2-checkpoint.ipynb @@ -0,0 +1,975 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# 1" + ] + }, + { + "cell_type": "code", + "execution_count": 166, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# -*- coding: utf-8 -*-\n", + "## Implementation of AVL tree\n", + "#\n", + "# Author: Tim Rijavec\n", + "# tim@coder.si\n", + "# http://coder.si\n", + "\n", + "class avlnode(object):\n", + " \"\"\"\n", + " A node in an avl tree.\n", + " \"\"\"\n", + "\n", + " def __init__(self, key):\n", + " \"Construct.\"\n", + "\n", + " # The node's key\n", + " self.key = key\n", + " # The node's left child\n", + " self.left = None\n", + " # The node's right child\n", + " self.right = None\n", + "\n", + " def __str__(self):\n", + " \"String representation.\"\n", + " return str(self.key)\n", + "\n", + " def __repr__(self):\n", + " \"String representation.\"\n", + " return str(self.key)\n", + "\n", + "class avltree(object):\n", + " \"\"\"\n", + " An avl tree.\n", + " \"\"\"\n", + "\n", + " def __init__(self):\n", + " \"Construct.\"\n", + "\n", + " # Root node of the tree.\n", + " self.node = None\n", + " # Height of the tree.\n", + " self.height = -1\n", + " # Balance factor of the tree.\n", + " self.balance = 0\n", + "\n", + " def insert(self, key):\n", + " \"\"\"\n", + " Insert new key into node\n", + " \"\"\"\n", + " # Create new node\n", + "\n", + "\n", + " # Initial tree\n", + " if not self.node:\n", + " n = avlnode(key)\n", + " self.node = n\n", + " self.node.left = avltree()\n", + " self.node.right = avltree()\n", + " # Insert key to the left subtree\n", + " elif key < self.node.key:\n", + " self.node.left.insert(key)\n", + " # Insert key to the right subtree\n", + " elif key > self.node.key:\n", + " self.node.right.insert(key)\n", + "\n", + " # Rebalance tree if needed\n", + " self.rebalance()\n", + "\n", + " def rebalance(self):\n", + " \"\"\"\n", + " Rebalance tree. After inserting or deleting a node,\n", + " it is necessary to check each of the node's ancestors for consistency with the rules of AVL\n", + " \"\"\"\n", + "\n", + " # Check if we need to rebalance the tree\n", + " # update height\n", + " # balance tree\n", + " self.update_heights(recursive=False)\n", + " self.update_balances(False)\n", + "\n", + " # For each node checked,\n", + " # if the balance factor remains −1, 0, or +1 then no rotations are necessary.\n", + " while self.balance < -1 or self.balance > 1:\n", + " # Left subtree is larger than right subtree\n", + " if self.balance > 1:\n", + "\n", + " # Left Right Case -> rotate y,z to the left\n", + " if self.node.left.balance < 0:\n", + " # x x\n", + " # / \\ / \\\n", + " # y D z D\n", + " # / \\ -> / \\\n", + " # A z y C\n", + " # / \\ / \\\n", + " # B C A B\n", + " self.node.left.rotate_left()\n", + " self.update_heights()\n", + " self.update_balances()\n", + "\n", + " # Left Left Case -> rotate z,x to the right\n", + " # x z\n", + " # / \\ / \\\n", + " # z D y x\n", + " # / \\ -> / \\ / \\\n", + " # y C A B C D\n", + " # / \\\n", + " # A B\n", + " self.rotate_right()\n", + " self.update_heights()\n", + " self.update_balances()\n", + "\n", + " # Right subtree is larger than left subtree\n", + " if self.balance < -1:\n", + "\n", + " # Right Left Case -> rotate x,z to the right\n", + " if self.node.right.balance > 0:\n", + " # y y\n", + " # / \\ / \\\n", + " # A x A z\n", + " # / \\ -> / \\\n", + " # z D B x\n", + " # / \\ / \\\n", + " # B C C D\n", + " self.node.right.rotate_right() # we're in case III\n", + " self.update_heights()\n", + " self.update_balances()\n", + "\n", + " # Right Right Case -> rotate y,x to the left\n", + " # y z\n", + " # / \\ / \\\n", + " # A z y x\n", + " # / \\ -> / \\ / \\\n", + " # B x A B C D\n", + " # / \\\n", + " # C D\n", + " self.rotate_left()\n", + " self.update_heights()\n", + " self.update_balances()\n", + "\n", + " def update_heights(self, recursive=True):\n", + " \"\"\"\n", + " Update tree height\n", + "\n", + " Tree height is max height of either left or right subtrees +1 for root of the tree\n", + " \"\"\"\n", + " if self.node:\n", + " if recursive:\n", + " if self.node.left:\n", + " self.node.left.update_heights()\n", + " if self.node.right:\n", + " self.node.right.update_heights()\n", + "\n", + " self.height = 1 + max(self.node.left.height, self.node.right.height)\n", + " else:\n", + " self.height = -1\n", + "\n", + " def update_balances(self, recursive=True):\n", + " \"\"\"\n", + " Calculate tree balance factor\n", + "\n", + " The balance factor is calculated as follows:\n", + " balance = height(left subtree) - height(right subtree).\n", + " \"\"\"\n", + " if self.node:\n", + " if recursive:\n", + " if self.node.left:\n", + " self.node.left.update_balances()\n", + " if self.node.right:\n", + " self.node.right.update_balances()\n", + "\n", + " self.balance = self.node.left.height - self.node.right.height\n", + " else:\n", + " self.balance = 0\n", + "\n", + "\n", + " def rotate_right(self):\n", + " \"\"\"\n", + " Right rotation\n", + " set self as the right subtree of left subree\n", + " \"\"\"\n", + " new_root = self.node.left.node\n", + " new_left_sub = new_root.right.node\n", + " old_root = self.node\n", + "\n", + " self.node = new_root\n", + " old_root.left.node = new_left_sub\n", + " new_root.right.node = old_root\n", + "\n", + " def rotate_left(self):\n", + " \"\"\"\n", + " Left rotation\n", + " set self as the left subtree of right subree\n", + " \"\"\"\n", + " new_root = self.node.right.node\n", + " new_left_sub = new_root.left.node\n", + " old_root = self.node\n", + "\n", + " self.node = new_root\n", + " old_root.right.node = new_left_sub\n", + " new_root.left.node = old_root\n", + "\n", + " def delete(self, key):\n", + " \"\"\"\n", + " Delete key from the tree\n", + "\n", + " Let node X be the node with the value we need to delete,\n", + " and let node Y be a node in the tree we need to find to take node X's place,\n", + " and let node Z be the actual node we take out of the tree.\n", + "\n", + " Steps to consider when deleting a node in an AVL tree are the following:\n", + "\n", + " * If node X is a leaf or has only one child, skip to step 5. (node Z will be node X)\n", + " * Otherwise, determine node Y by finding the largest node in node X's left sub tree\n", + " (in-order predecessor) or the smallest in its right sub tree (in-order successor).\n", + " * Replace node X with node Y (remember, tree structure doesn't change here, only the values).\n", + " In this step, node X is essentially deleted when its internal values were overwritten with node Y's.\n", + " * Choose node Z to be the old node Y.\n", + " * Attach node Z's subtree to its parent (if it has a subtree). If node Z's parent is null,\n", + " update root. (node Z is currently root)\n", + " * Delete node Z.\n", + " * Retrace the path back up the tree (starting with node Z's parent) to the root,\n", + " adjusting the balance factors as needed.\n", + " \"\"\"\n", + " if self.node != None:\n", + " if self.node.key == key:\n", + " # Key found in leaf node, just erase it\n", + " if not self.node.left.node and not self.node.right.node:\n", + " self.node = None\n", + " # Node has only one subtree (right), replace root with that one\n", + " elif not self.node.left.node:\n", + " self.node = self.node.right.node\n", + " # Node has only one subtree (left), replace root with that one\n", + " elif not self.node.right.node:\n", + " self.node = self.node.left.node\n", + " else:\n", + " # Find successor as smallest node in right subtree or\n", + " # predecessor as largest node in left subtree\n", + " successor = self.node.right.node\n", + " while successor and successor.left.node:\n", + " successor = successor.left.node\n", + "\n", + " if successor:\n", + " self.node.key = successor.key\n", + "\n", + " # Delete successor from the replaced node right subree\n", + " self.node.right.delete(successor.key)\n", + "\n", + " elif key < self.node.key:\n", + " self.node.left.delete(key)\n", + "\n", + " elif key > self.node.key:\n", + " self.node.right.delete(key)\n", + "\n", + " # Rebalance tree\n", + " self.rebalance()\n", + "\n", + " def inorder_traverse(self):\n", + " \"\"\"\n", + " Inorder traversal of the tree\n", + " Left subree + root + Right subtree\n", + " \"\"\"\n", + " result = []\n", + "\n", + " if not self.node:\n", + " return result\n", + "\n", + " result.extend(self.node.left.inorder_traverse())\n", + " result.append(self.node.key)\n", + " result.extend(self.node.right.inorder_traverse())\n", + "\n", + " return result\n", + "\n", + " def display(self, node=None, level=0):\n", + " if not node:\n", + " node = self.node\n", + "\n", + " if node.right.node:\n", + " self.display(node.right.node, level + 1)\n", + " print ('\\t' * level), (' /')\n", + "\n", + " print ('\\t' * level), node\n", + "\n", + " if node.left.node:\n", + " print ('\\t' * level), (' \\\\')\n", + " self.display(node.left.node, level + 1)\n", + "\n", + "\n", + " def find_key(self,key,symbol = \"==\"):\n", + " \"\"\"we are saying node.key symbol(==,>=) key \"\"\"\n", + " if symbol in [\"==\"]:\n", + " if not self.node:\n", + " node_to_return = None\n", + " elif self.node.key == key:\n", + " node_to_return = self.node\n", + " elif self.node.key < key:\n", + " node_to_return = self.node.right.find_key(key,symbol)\n", + " elif self.node.key > key:\n", + " node_to_return = self.node.left.find_key(key,symbol)\n", + "\n", + " return node_to_return\n", + "\n", + "\n", + " if symbol in [\"<=\"]:\n", + " if not self.node:\n", + " node_to_return = None\n", + " elif self.node.key == key:\n", + " node_to_return = self.node\n", + " elif self.node.key < key:\n", + " node_to_return = self.node.right.find_key(key,symbol)\n", + " if not node_to_return:\n", + " node_to_return = self.node\n", + " elif self.node.key > key:\n", + " node_to_return = self.node.left.find_key(key,symbol)\n", + " return node_to_return\n", + "\n", + " if symbol in [\"<\"]:\n", + " if not self.node:\n", + " node_to_return = None\n", + " # elif self.node.key == key:\n", + " # node_to_return = self.node\n", + " elif self.node.key < key:\n", + " node_to_return = self.node.right.find_key(key,symbol)\n", + " if not node_to_return:\n", + " node_to_return = self.node\n", + " elif self.node.key >= key:\n", + " node_to_return = self.node.left.find_key(key,symbol)\n", + "\n", + " return node_to_return\n", + "\n", + "\n", + " if symbol in [\">=\"]:\n", + " if not self.node:\n", + " node_to_return = None\n", + " elif self.node.key == key:\n", + " node_to_return = self.node\n", + " elif self.node.key < key:\n", + " node_to_return = self.node.right.find_key(key,symbol)\n", + " elif self.node.key > key:\n", + " node_to_return = self.node.left.find_key(key,symbol)\n", + " if not node_to_return:\n", + " node_to_return = self.node\n", + " return node_to_return\n", + "\n", + " if symbol in [\">\"]:\n", + " if not self.node:\n", + " node_to_return = None\n", + " # elif self.node.key == key:\n", + " # node_to_return = self.node\n", + " elif self.node.key <= key:\n", + " node_to_return = self.node.right.find_key(key,symbol)\n", + " elif self.node.key > key:\n", + " node_to_return = self.node.left.find_key(key,symbol)\n", + " if not node_to_return:\n", + " node_to_return = self.node\n", + " return node_to_return\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 2" + ] + }, + { + "cell_type": "code", + "execution_count": 188, + "metadata": {}, + "outputs": [], + "source": [ + "tree = avltree()\n", + "data = range(20)\n", + "\n", + "from random import randrange\n", + "for key in data: \n", + " tree.insert(key)\n", + "\n", + "for key in [4,3,68,69]:\n", + " tree.delete(key)\n", + "\n", + "# print tree.inorder_traverse()\n", + "# tree.display()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 189, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]" + ] + }, + "execution_count": 189, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tree.inorder_traverse()" + ] + }, + { + "cell_type": "code", + "execution_count": 190, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(9)" + ] + }, + { + "cell_type": "code", + "execution_count": 191, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9" + ] + }, + "execution_count": 191, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 192, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.delete(7)" + ] + }, + { + "cell_type": "code", + "execution_count": 193, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 1, 2, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]" + ] + }, + "execution_count": 193, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tree.inorder_traverse()" + ] + }, + { + "cell_type": "code", + "execution_count": 194, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(7)" + ] + }, + { + "cell_type": "code", + "execution_count": 195, + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'NoneType' object has no attribute 'key'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mnode_got\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m: 'NoneType' object has no attribute 'key'" + ] + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 196, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 1, 2, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]" + ] + }, + "execution_count": 196, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tree.inorder_traverse()" + ] + }, + { + "cell_type": "code", + "execution_count": 197, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(12,\"<=\")" + ] + }, + { + "cell_type": "code", + "execution_count": 198, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12" + ] + }, + "execution_count": 198, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 199, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(10.1,\"<=\")" + ] + }, + { + "cell_type": "code", + "execution_count": 200, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 200, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 201, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(12,\"<\")" + ] + }, + { + "cell_type": "code", + "execution_count": 202, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "11" + ] + }, + "execution_count": 202, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 203, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(11.2,\"<\")" + ] + }, + { + "cell_type": "code", + "execution_count": 204, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "11" + ] + }, + "execution_count": 204, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 205, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(12,\">=\")" + ] + }, + { + "cell_type": "code", + "execution_count": 206, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12" + ] + }, + "execution_count": 206, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 207, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(10.1,\">=\")" + ] + }, + { + "cell_type": "code", + "execution_count": 208, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "11" + ] + }, + "execution_count": 208, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 209, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(12,\">\")" + ] + }, + { + "cell_type": "code", + "execution_count": 210, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "13" + ] + }, + "execution_count": 210, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 211, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(10.1,\">\")" + ] + }, + { + "cell_type": "code", + "execution_count": 212, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "11" + ] + }, + "execution_count": 212, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 213, + "metadata": {}, + "outputs": [], + "source": [ + "tree.delete(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 214, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12" + ] + }, + "execution_count": 214, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got = tree.find_key(10.1,\">\")\n", + "\n", + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# tree.inorder_traverse()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/.ipynb_checkpoints/Untitled3-checkpoint.ipynb b/.ipynb_checkpoints/Untitled3-checkpoint.ipynb new file mode 100644 index 00000000..2fd64429 --- /dev/null +++ b/.ipynb_checkpoints/Untitled3-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/BredthFirstSearch.py b/BredthFirstSearch.py new file mode 100644 index 00000000..a8f51fc3 --- /dev/null +++ b/BredthFirstSearch.py @@ -0,0 +1,53 @@ +# vertices or nodes in a given graph +class Node(object): + def __init__(self , name): + self.name = name # Name of Node + self.adjacencyList = [] # Adjacency List + self.visited = False # Boolean check if visited node or not + self.predecessor = None # previous Vertex/Node in BFS +# Bredth First Search +class BredthFirstSearch(object): + # startNode: Starting Node from where we need to start BFS + def bfs(self,startNode): + #For BFS, using Queue as ADT + queue=[] + #Initially , first value in the queue + queue.append(startNode) + #That node is visited, so true + startNode.visited = True + + + # while queue is not empty + while queue: + # actual node is the first node. FIFO Queue + actualNode = queue.pop(0) + print('%s'% actualNode.name) + + + #visit all Neighbors of the current Node + for n in actualNode.adjacencyList: + #If Neighboring Node has not been visited, set visited to True and add to queue + if not n.visited: + n.visited = True + queue.append(n) + + +#Testing +if __name__=='__main__': + node1 = Node('Á') + node2 = Node('B') + node3 = Node('C') + node4 = Node('D') + node5 = Node('E') + node6 = Node('F') + + node1.adjacencyList.append(node2) + node1.adjacencyList.append(node3) + node2.adjacencyList.append(node4) + node4.adjacencyList.append(node5) + node4.adjacencyList.append(node6) + + BFS = BredthFirstSearch() + BFS.bfs(node1) + + # -------------------------- EOC -------------------------- \ No newline at end of file diff --git a/EPAT.ipynb b/EPAT.ipynb new file mode 100644 index 00000000..9c858ad2 --- /dev/null +++ b/EPAT.ipynb @@ -0,0 +1,645 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "EPAT.ipynb", + "version": "0.3.2", + "provenance": [], + "collapsed_sections": [], + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "[View in Colaboratory](https://colab.research.google.com/github/anilsrik/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/EPAT.ipynb)" + ] + }, + { + "metadata": { + "id": "mvQLQMXtzCdq", + "colab_type": "code", + "colab": {} + }, + "cell_type": "code", + "source": [ + "from google.colab import drive\n", + "drive.mount('/content/gdrive')" + ], + "execution_count": 0, + "outputs": [] + }, + { + "metadata": { + "id": "NvFwp1fyxkVr", + "colab_type": "code", + "colab": {} + }, + "cell_type": "code", + "source": [ + "import numpy as np\n", + "from statsmodels.tsa.tsatools import lagmat\n", + "from numpy.linalg import inv\n", + "from statsmodels.tsa.coint_tables import c_sja, c_sjt\n", + "\n", + "def coint_johansen_1(endog, det_order, k_ar_diff):\n", + " \"\"\"\n", + " Perform the Johansen cointegration test for determining the cointegration\n", + " rank of a VECM.\n", + " Parameters\n", + " ----------\n", + " endog : array-like (nobs_tot x neqs)\n", + " The data with presample.\n", + " det_order : int\n", + " * -1 - no deterministic terms\n", + " * 0 - constant term\n", + " * 1 - linear trend\n", + " k_ar_diff : int, nonnegative\n", + " Number of lagged differences in the model.\n", + " Returns\n", + " -------\n", + " result : Holder\n", + " An object containing the results which can be accessed using\n", + " dot-notation. The object's attributes are\n", + " * eig: (neqs)\n", + " Eigenvalues.\n", + " * evec: (neqs x neqs)\n", + " Eigenvectors.\n", + " * lr1: (neqs)\n", + " Trace statistic.\n", + " * lr2: (neqs)\n", + " Maximum eigenvalue statistic.\n", + " * cvt: (neqs x 3)\n", + " Critical values (90%, 95%, 99%) for trace statistic.\n", + " * cvm: (neqs x 3)\n", + " Critical values (90%, 95%, 99%) for maximum eigenvalue\n", + " statistic.\n", + " * method: str\n", + " \"johansen\"\n", + " * r0t: (nobs x neqs)\n", + " Residuals for :math:`\\\\Delta Y`. See p. 292 in [1]_.\n", + " * rkt: (nobs x neqs)\n", + " Residuals for :math:`Y_{-1}`. See p. 292 in [1]_.\n", + " * ind: (neqs)\n", + " Order of eigenvalues.\n", + " Notes\n", + " -----\n", + " The implementation might change to make more use of the existing VECM\n", + " framework.\n", + " References\n", + " ----------\n", + " .. [1] Lütkepohl, H. 2005. *New Introduction to Multiple Time Series Analysis*. Springer.\n", + " \"\"\"\n", + " import warnings\n", + " if det_order not in [-1, 0, 1]:\n", + " warnings.warn(\"Critical values are only available for a det_order of \"\n", + " \"-1, 0, or 1.\", category=HypothesisTestWarning)\n", + " if endog.shape[1] > 12: # todo: test with a time series of 13 variables\n", + " warnings.warn(\"Critical values are only available for time series \"\n", + " \"with 12 variables at most.\",\n", + " category=HypothesisTestWarning)\n", + "\n", + " from statsmodels.regression.linear_model import OLS\n", + "\n", + " class Holder(object):\n", + " pass\n", + "\n", + " def detrend(y, order):\n", + " if order == -1:\n", + " return y\n", + " return OLS(y, np.vander(np.linspace(-1, 1, len(y)),\n", + " order+1)).fit().resid\n", + "\n", + " def resid(y, x):\n", + " if x.size == 0:\n", + " return y\n", + " r = y - np.dot(x, np.dot(np.linalg.pinv(x), y))\n", + " return r\n", + "\n", + " nobs, neqs = endog.shape\n", + "\n", + " # why this? f is detrend transformed series, det_order is detrend data\n", + " if det_order > -1:\n", + " f = 0\n", + " else:\n", + " f = det_order\n", + "\n", + " endog = detrend(endog, det_order)\n", + " dx = np.diff(endog, 1, axis=0)\n", + " z = lagmat(dx, k_ar_diff)\n", + " z = z[k_ar_diff:]\n", + " z = detrend(z, f)\n", + "\n", + " dx = dx[k_ar_diff:]\n", + "\n", + " dx = detrend(dx, f)\n", + " r0t = resid(dx, z)\n", + " lx = endog[:-k_ar_diff]\n", + " lx = lx[1:]\n", + " dx = detrend(lx, f)\n", + " rkt = resid(dx, z) # level on lagged diffs\n", + " skk = np.dot(rkt.T, rkt) / rkt.shape[0]\n", + " sk0 = np.dot(rkt.T, r0t) / rkt.shape[0]\n", + " s00 = np.dot(r0t.T, r0t) / r0t.shape[0]\n", + " sig = np.dot(sk0, np.dot(inv(s00), sk0.T))\n", + " tmp = inv(skk)\n", + " au, du = np.linalg.eig(np.dot(tmp, sig)) # au is eval, du is evec\n", + "\n", + " temp = inv(np.linalg.cholesky(np.dot(du.T, np.dot(skk, du))))\n", + " dt = np.dot(du, temp)\n", + "\n", + " # JP: the next part can be done much easier\n", + " auind = np.argsort(au)\n", + " aind = np.flipud(auind)\n", + " a = au[aind]\n", + " d = dt[:, aind]\n", + "\n", + " # Compute the trace and max eigenvalue statistics\n", + " lr1 = np.zeros(neqs)\n", + " lr2 = np.zeros(neqs)\n", + " cvm = np.zeros((neqs, 3))\n", + " cvt = np.zeros((neqs, 3))\n", + " iota = np.ones(neqs)\n", + " t, junk = rkt.shape\n", + " for i in range(0, neqs):\n", + " tmp = np.log(iota - a)[i:]\n", + " lr1[i] = -t * np.sum(tmp, 0)\n", + " lr2[i] = -t * np.log(1-a[i])\n", + " cvm[i, :] = c_sja(neqs - i, det_order)\n", + " cvt[i, :] = c_sjt(neqs - i, det_order)\n", + " aind[i] = i\n", + "\n", + " result = Holder()\n", + " # estimation results, residuals\n", + " result.rkt = rkt\n", + " result.r0t = r0t\n", + " result.eig = a\n", + " result.evec = d\n", + " result.lr1 = lr1\n", + " result.lr2 = lr2\n", + " result.cvt = cvt\n", + " result.cvm = cvm\n", + " result.ind = aind\n", + " result.meth = 'johansen'\n", + "\n", + " return result\n" + ], + "execution_count": 0, + "outputs": [] + }, + { + "metadata": { + "id": "BTQJJZXF2-AR", + "colab_type": "code", + "colab": {} + }, + "cell_type": "code", + "source": [ + "import statsmodels as sm\n", + "import statsmodels.api as smapi\n", + "from numpy import zeros, ones, flipud, log\n", + "from numpy.linalg import inv, eig, cholesky as chol\n", + "from statsmodels.regression.linear_model import OLS\n", + "tdiff = np.diff\n", + "\n", + "ss_ejcp0 = '''\\\n", + " 2.9762 4.1296 6.9406\n", + " 9.4748 11.2246 15.0923\n", + " 15.7175 17.7961 22.2519\n", + " 21.8370 24.1592 29.0609\n", + " 27.9160 30.4428 35.7359\n", + " 33.9271 36.6301 42.2333\n", + " 39.9085 42.7679 48.6606\n", + " 45.8930 48.8795 55.0335\n", + " 51.8528 54.9629 61.3449\n", + " 57.7954 61.0404 67.6415\n", + " 63.7248 67.0756 73.8856\n", + " 69.6513 73.0946 80.0937'''\n", + "\n", + "ss_ejcp1 = '''\\\n", + " 2.7055 3.8415 6.6349\n", + " 12.2971 14.2639 18.5200\n", + " 18.8928 21.1314 25.8650\n", + " 25.1236 27.5858 32.7172\n", + " 31.2379 33.8777 39.3693\n", + " 37.2786 40.0763 45.8662\n", + " 43.2947 46.2299 52.3069\n", + " 49.2855 52.3622 58.6634\n", + " 55.2412 58.4332 64.9960\n", + " 61.2041 64.5040 71.2525\n", + " 67.1307 70.5392 77.4877\n", + " 73.0563 76.5734 83.7105'''\n", + "\n", + "ss_ejcp2 = '''\\\n", + " 2.7055 3.8415 6.6349\n", + " 15.0006 17.1481 21.7465\n", + " 21.8731 24.2522 29.2631\n", + " 28.2398 30.8151 36.1930\n", + " 34.4202 37.1646 42.8612\n", + " 40.5244 43.4183 49.4095\n", + " 46.5583 49.5875 55.8171\n", + " 52.5858 55.7302 62.1741\n", + " 58.5316 61.8051 68.5030\n", + " 64.5292 67.9040 74.7434\n", + " 70.4630 73.9355 81.0678\n", + " 76.4081 79.9878 87.2395'''\n", + "\n", + "ejcp0 = np.array(ss_ejcp0.split(),float).reshape(-1,3)\n", + "ejcp1 = np.array(ss_ejcp1.split(),float).reshape(-1,3)\n", + "ejcp2 = np.array(ss_ejcp2.split(),float).reshape(-1,3)\n", + "\n", + "def c_sja(n, p):\n", + " if ((p > 1) or (p < -1)):\n", + " jc = np.zeros(3)\n", + " elif ((n > 12) or (n < 1)):\n", + " jc = np.zeros(3)\n", + " elif p == -1:\n", + " jc = ejcp0[n-1,:]\n", + " elif p == 0:\n", + " jc = ejcp1[n-1,:]\n", + " elif p == 1:\n", + " jc = ejcp2[n-1,:]\n", + "\n", + " return jc\n", + "\n", + "ss_tjcp0 = '''\\\n", + " 2.9762 4.1296 6.9406\n", + " 10.4741 12.3212 16.3640\n", + " 21.7781 24.2761 29.5147\n", + " 37.0339 40.1749 46.5716\n", + " 56.2839 60.0627 67.6367\n", + " 79.5329 83.9383 92.7136\n", + " 106.7351 111.7797 121.7375\n", + " 137.9954 143.6691 154.7977\n", + " 173.2292 179.5199 191.8122\n", + " 212.4721 219.4051 232.8291\n", + " 255.6732 263.2603 277.9962\n", + " 302.9054 311.1288 326.9716'''\n", + "\n", + "\n", + "ss_tjcp1 = '''\\\n", + " 2.7055 3.8415 6.6349\n", + " 13.4294 15.4943 19.9349\n", + " 27.0669 29.7961 35.4628\n", + " 44.4929 47.8545 54.6815\n", + " 65.8202 69.8189 77.8202\n", + " 91.1090 95.7542 104.9637\n", + " 120.3673 125.6185 135.9825\n", + " 153.6341 159.5290 171.0905\n", + " 190.8714 197.3772 210.0366\n", + " 232.1030 239.2468 253.2526\n", + " 277.3740 285.1402 300.2821\n", + " 326.5354 334.9795 351.2150'''\n", + "\n", + "ss_tjcp2 = '''\\\n", + " 2.7055 3.8415 6.6349\n", + " 16.1619 18.3985 23.1485\n", + " 32.0645 35.0116 41.0815\n", + " 51.6492 55.2459 62.5202\n", + " 75.1027 79.3422 87.7748\n", + " 102.4674 107.3429 116.9829\n", + " 133.7852 139.2780 150.0778\n", + " 169.0618 175.1584 187.1891\n", + " 208.3582 215.1268 228.2226\n", + " 251.6293 259.0267 273.3838\n", + " 298.8836 306.8988 322.4264\n", + " 350.1125 358.7190 375.3203'''\n", + "\n", + "tjcp0 = np.array(ss_tjcp0.split(),float).reshape(-1,3)\n", + "tjcp1 = np.array(ss_tjcp1.split(),float).reshape(-1,3)\n", + "tjcp2 = np.array(ss_tjcp2.split(),float).reshape(-1,3)\n", + "\n", + "def c_sjt(n, p):\n", + " if ((p > 1) or (p < -1)):\n", + " jc = np.zeros(3)\n", + " elif ((n > 12) or (n < 1)):\n", + " jc = np.zeros(3)\n", + " elif p == -1:\n", + " jc = tjcp0[n-1,:]\n", + " elif p == 0:\n", + " jc = tjcp1[n-1,:]\n", + " elif p == 1:\n", + " jc = tjcp2[n-1,:]\n", + " else:\n", + " raise ValueError('invalid p')\n", + "\n", + " return jc\n", + "\n", + "\n", + "class Holder(object):\n", + " pass\n", + "\n", + "def rows(x):\n", + " return x.shape[0]\n", + "\n", + "def trimr(x, front, end):\n", + " if end > 0:\n", + " return x[front:-end]\n", + " else:\n", + " return x[front:]\n", + "\n", + "import statsmodels.tsa.tsatools as tsat\n", + "mlag = tsat.lagmat\n", + "\n", + "def mlag_(x, maxlag):\n", + " '''return all lags up to maxlag\n", + " '''\n", + " return x[:-lag]\n", + "\n", + "def lag(x, lag):\n", + " return x[:-lag]\n", + "\n", + "def detrend(y, order):\n", + " if order == -1:\n", + " return y\n", + " return OLS(y, np.vander(np.linspace(-1,1,len(y)), order+1)).fit().resid\n", + "\n", + "def resid(y, x):\n", + " if x.size == 0:\n", + " return y\n", + " try:\n", + " r = y - np.dot(x, np.dot(np.linalg.pinv(x), y))\n", + " except:\n", + " return None\n", + " return r\n", + "\n", + "\n", + "def coint_johansen(x, p, k, coint_trend=None):\n", + "\n", + " # % error checking on inputs\n", + " # if (nargin ~= 3)\n", + " # error('Wrong # of inputs to johansen')\n", + " # end\n", + " nobs, m = x.shape\n", + "\n", + " #why this? f is detrend transformed series, p is detrend data\n", + " if (p > -1):\n", + " f = 0\n", + " else:\n", + " f = p\n", + "\n", + " if coint_trend is not None:\n", + " f = coint_trend #matlab has separate options\n", + "\n", + " x = detrend(x,p)\n", + " dx = tdiff(x,1, axis=0)\n", + " #dx = trimr(dx,1,0)\n", + " z = mlag(dx,k)#[k-1:]\n", + " z = trimr(z,k,0)\n", + " z = detrend(z,f)\n", + " dx = trimr(dx,k,0)\n", + "\n", + " dx = detrend(dx,f)\n", + " #r0t = dx - z*(z\\dx)\n", + " r0t = resid(dx, z) #diff on lagged diffs\n", + " #lx = trimr(lag(x,k),k,0)\n", + " lx = lag(x,k)\n", + " lx = trimr(lx, 1, 0)\n", + " dx = detrend(lx,f)\n", + " #rkt = dx - z*(z\\dx)\n", + " rkt = resid(dx, z) #level on lagged diffs\n", + " if rkt is None:\n", + " return None\n", + " skk = np.dot(rkt.T, rkt) / rows(rkt)\n", + " sk0 = np.dot(rkt.T, r0t) / rows(rkt)\n", + " s00 = np.dot(r0t.T, r0t) / rows(r0t)\n", + " try:\n", + " sig = np.dot(sk0, np.dot(inv(s00), (sk0.T)))\n", + " except:\n", + " return None\n", + "\n", + " try:\n", + " tmp = inv(skk)\n", + " except:\n", + " return None\n", + " \n", + " #du, au = eig(np.dot(tmp, sig))\n", + " au, du = eig(np.dot(tmp, sig)) #au is eval, du is evec\n", + " #orig = np.dot(tmp, sig)\n", + " try:\n", + " #% Normalize the eigen vectors such that (du'skk*du) = I\n", + " temp = inv(chol(np.dot(du.T, np.dot(skk, du))))\n", + " except:\n", + " return None\n", + " dt = np.dot(du, temp)\n", + "\n", + "\n", + " #JP: the next part can be done much easier\n", + "\n", + " #% NOTE: At this point, the eigenvectors are aligned by column. To\n", + " #% physically move the column elements using the MATLAB sort,\n", + " #% take the transpose to put the eigenvectors across the row\n", + "\n", + " #dt = transpose(dt)\n", + "\n", + " #% sort eigenvalues and vectors\n", + "\n", + " #au, auind = np.sort(diag(au))\n", + " auind = np.argsort(au)\n", + " #a = flipud(au)\n", + " aind = flipud(auind)\n", + " a = au[aind]\n", + " #d = dt[aind,:]\n", + " d = dt[:,aind]\n", + "\n", + " #%NOTE: The eigenvectors have been sorted by row based on auind and moved to array \"d\".\n", + " #% Put the eigenvectors back in column format after the sort by taking the\n", + " #% transpose of \"d\". Since the eigenvectors have been physically moved, there is\n", + " #% no need for aind at all. To preserve existing programming, aind is reset back to\n", + " #% 1, 2, 3, ....\n", + "\n", + " #d = transpose(d)\n", + " #test = np.dot(transpose(d), np.dot(skk, d))\n", + "\n", + " #%EXPLANATION: The MATLAB sort function sorts from low to high. The flip realigns\n", + " #%auind to go from the largest to the smallest eigenvalue (now aind). The original procedure\n", + " #%physically moved the rows of dt (to d) based on the alignment in aind and then used\n", + " #%aind as a column index to address the eigenvectors from high to low. This is a double\n", + " #%sort. If you wanted to extract the eigenvector corresponding to the largest eigenvalue by,\n", + " #%using aind as a reference, you would get the correct eigenvector, but with sorted\n", + " #%coefficients and, therefore, any follow-on calculation would seem to be in error.\n", + " #%If alternative programming methods are used to evaluate the eigenvalues, e.g. Frame method\n", + " #%followed by a root extraction on the characteristic equation, then the roots can be\n", + " #%quickly sorted. One by one, the corresponding eigenvectors can be generated. The resultant\n", + " #%array can be operated on using the Cholesky transformation, which enables a unit\n", + " #%diagonalization of skk. But nowhere along the way are the coefficients within the\n", + " #%eigenvector array ever changed. The final value of the \"beta\" array using either method\n", + " #%should be the same.\n", + "\n", + "\n", + " #% Compute the trace and max eigenvalue statistics */\n", + " lr1 = zeros(m)\n", + " lr2 = zeros(m)\n", + " cvm = zeros((m,3))\n", + " cvt = zeros((m,3))\n", + " iota = ones(m)\n", + " t, junk = rkt.shape\n", + " for i in range(0, m):\n", + " tmp = trimr(np.log(iota-a), i ,0)\n", + " lr1[i] = -t * np.sum(tmp, 0) #columnsum ?\n", + " #tmp = np.log(1-a)\n", + " #lr1[i] = -t * np.sum(tmp[i:])\n", + " lr2[i] = -t * np.log(1-a[i])\n", + " cvm[i,:] = c_sja(m-i,p)\n", + " cvt[i,:] = c_sjt(m-i,p)\n", + " aind[i] = i\n", + " #end\n", + "\n", + " result = Holder()\n", + " #% set up results structure\n", + " #estimation results, residuals\n", + " result.rkt = rkt\n", + " result.r0t = r0t\n", + " result.eig = a\n", + " result.evec = d #transposed compared to matlab ?\n", + " result.lr1 = lr1\n", + " result.lr2 = lr2\n", + " result.cvt = cvt\n", + " result.cvm = cvm\n", + " result.ind = aind\n", + " result.meth = 'johansen'\n", + "\n", + " return result\n", + "\n" + ], + "execution_count": 0, + "outputs": [] + }, + { + "metadata": { + "id": "SNM-rIMVydgk", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 365 + }, + "outputId": "9f3bb035-907c-4c84-b42e-6f5d27c53514" + }, + "cell_type": "code", + "source": [ + "import pandas as pd\n", + "xlf = pd.read_csv(\"/content/gdrive/My Drive/EPAT/Data/XLF.csv\", parse_dates=True, index_col=\"Date\")\n", + "jpm = pd.read_csv(\"/content/gdrive/My Drive/EPAT/Data/JPM.csv\", parse_dates=True, index_col=\"Date\")\n", + "bac = pd.read_csv(\"/content/gdrive/My Drive/EPAT/Data/BAC.csv\", parse_dates=True, index_col=\"Date\")\n", + "c = pd.read_csv(\"/content/gdrive/My Drive/EPAT/Data/C.csv\", parse_dates=True, index_col=\"Date\")\n", + "#Merge to remove any missing data elements from each data frame. A data quality check.\n", + "df = xlf.merge(jpm, left_index=True, right_index=True, suffixes=('', \"_jpm\")).merge(bac,left_index=True,right_index=True,suffixes=(\"\",\"_bac\")).merge(c,left_index=True,right_index=True,suffixes=(\"\",\"_c\"))\n", + "series_df = df[[\"Open\", \"Open_jpm\", \"Open_bac\", \"Open_c\"]].copy().rename(columns={\"Open\":\"XLF\", \"Open_jpm\":\"JPM\", \"Open_bac\":\"BAC\", \"Open_c\":\"C\"})\n", + "series_df.plot()" + ], + "execution_count": 0, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 34 + }, + { + "output_type": "display_data", + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeQAAAFLCAYAAAAH5P/CAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAIABJREFUeJzs3WdgVGXa8PH/9GQykz7phZBA6KF3\nRBAVuytrx8q669r31cfd1bXs6rr2XteGotgbsioioCggAqGXkBDSe51kMn3m/TCZk5l0Qircvy/O\nmXNy5j6AueZu1yVzu91uBEEQBEEYUPKBboAgCIIgCCIgC4IgCMKgIAKyIAiCIAwCIiALgiAIwiAg\nArIgCIIgDALKgfzwysqGgfz4HgkL01Jb2zTQzThu4jkGF/Ecg8eJ8AwgnmOw8T6HwaDv8BrRQz5G\nSqVioJvQK8RzDC7iOQaPE+EZQDzHYNOd5xABWRAEQRAGARGQBUEQBGEQEAFZEARBEAYBEZAFQRAE\nYRAQAVkQBEEQBoFuBeTDhw+zaNEi3nvvPQBKS0u59tprWbp0Kddeey2VlZUArFq1iiVLlnDxxRfz\nySef9F2rBUEQBOEE02VAbmpq4qGHHmLWrFnSe88++yyXXHIJ7733Hqeffjpvv/02TU1NvPTSSyxf\nvpwVK1bwzjvvUFdX16eNFwRBEIQTRZcBWa1W8/rrrxMVFSW998ADD3DmmWcCEBYWRl1dHbt372b8\n+PHo9XoCAgKYPHkymZmZfddyQRAEQTiBdJmpS6lUolT6X6bVagFwOp2sXLmSm2++maqqKsLDw6Vr\nwsPDpaHsoWTbtq28886bvPjifwGorKzgtttuZPbsucTFxXPjjX/wu/73vz+PqKho5PKW7zbenxUE\nQRCE7upx6kyn08ndd9/NzJkzmTVrFl9//bXfebfb3eU9wsK0gy4Ly9lnL+LHH79n06Z1XHjhhTzy\nyP3cddedZGdno9MFAPilPlMo5Cxf/hZBQUED1eQe6yyF21AinmNwORGe40R4BhDP0VNut5usqiOM\njBju19k6Xl09R48D8t///neSk5O55ZZbAIiKiqKqqko6X1FRwcSJEzu9x2DNT3rDDbdyyy034HQq\nqK2tZ8qUOezatQ+VygL45+B2Ol1UVTXS1OQaqOb2iMGgH5K5xFsTzzG4nAjPcSI8A/TtcxyozmJT\nyW9cO+YyVApVn3yG10D8fWwt3cG7Bz/ijOQFXJB6Vq/c0/scnQXlHgXkVatWoVKpuO2226T3MjIy\n+Mc//oHRaEShUJCZmck999zTk9tLPl6fw7ZDFcd1j9amjYrikoVpnV4TGhrKZZddyQMP/J333/+0\nVz9fEARhqHtp95sAHKqdwvjIMVidNuxOOzr10BspbM/BmmwAfiza1GsBuTu6DMj79u3jscceo7i4\nGKVSyZo1a6iurkaj0XDVVVcBkJqayoMPPsidd97JsmXLkMlk3Hzzzej1Q3e4JCcnm5iYWA4dOkhc\nXHyn1951123SsEZoaBgPP/xYfzRREARhQNmcdtxuN/du+jdymYzH5j6ATCYb6Ga14XQ5sTptaFWB\n3bpeIfP8Prc5bThdThTy/pla7TIgjxs3jhUrVnTrZosXL2bx4sXH3SivSxamddmb7QsHDuzj6NFc\nXnjhNe644yZmzpzd6fVPPvm8tNBNEAThZGG0NVDWVIHZYQbA6rQSoAwY4Fa19XnOan4s2sQ1Yy5j\neszkLq93uB3S64KGIlJCkvuyeRKRqasVh8PBU089xu2330VkpIGzzz6fN998baCbJQiCMCg02c3S\na6vTSnbtEenYZB9c64LKTRV8mfMNPxZtAuCdAx/6nc+tzyfPWNDm5+yuloBcYirr20b66PGirhPV\nhx++x8SJkxk+PBWASy65nGXLlpKQkMiRIzls2vQTNpuD4OAQHnnkiQFurSAIQt9wuV3kGQtJCU7y\nG4auttRIr61OG0WNpdKxyd5ERGA4g8UTO17E7LBIx/G6WL/zT+14CYCXFj7u977dZZdeH6rJZk7c\njD5sZQsRkFtZuvRav2OlUsk777R8q2q94u/TT/23ewmCIAxlFoeVSnM13xxdy56q/SwddTGz4qZJ\n56vMLQHZ5rRRaCySjmut9SSR0K/t7YxvMO5Mk70Jrapl2tHhcgIQoAigpFH0kAVBEIQB8GHWF2wr\nb8mymF2Xy6y4aeyp3I8LN5VNLdtby5sqqfLpMRc1lpBhGNuv7e2IxWFt815xYylWpw2NQo3d2dIL\nLjVVkBo6TDp2uOzIZXJCA0IwWo390VxABGRBEATBx46KXX7H3kVar+19p821B2sOAxCs1mO0NZBV\nk8MZyQtQyQc+tDy4xX+3S7wuluLGUt7Z/wFjItLZW3VAOldmKm8VkB0o5UqCVTrKTOXScV8Ti7oE\nQRAESWxQNACzYj3D1Ca7qcufCVbrSQ5O5Ej9Ud7c9x4ut3+ipCpzNXdtfIAD1Vm93+AONNgb/Y7P\nSTkdgIKGYj7I+px91YekcyuzPuOhrU/x1ZFvMdoasLscqGRKpsdOYVLUBBSy/tn2JAKyIAiCIKmz\n1hOtNXB5+kUA1LczZLt01MV+xxqFhtsm3kCIOpi9VQcoM/kndFpf+Atmh5k3973f7mfurtzP2/tX\n0tRLq7QdPqukvTIM44gLiqHW2lKFcGp0SzbJMlM53+dvYH3BzzTYGlHKlcyKncofxi3tt73VIiAL\ngiAIuNwu1hdsxGRvIlQTgkKuQK/SUW81+tUmWJA4l6nRE/2GpVVyJQHKAGnxV4PNv3caqNAAYHG2\nv8jq27wf2F6+i2d3vtamd90T3u1XU6IyOGvYaVwz5jLAs2/a688TruO6sVdwU8Yyv59dW/AjjXYT\nBm3EcbfjWImALAiCILC36gCf5awGIFQT0vzfYOpsRmlf7ujwkfx+xPmoFCo0zUEWkLY66VU6AEwO\n/56uRqmhMyq5Jx92cWMpRQ0lx/0s5U2eSoPBaj3nDj9TSgYyOnwkAEvSzmVc5GgAxkak88DMu7lz\nyk1+9+hOApHeJgJyB+688zbOP/9MPvvsI04//RRuueWP3HLLH7nkkkv46acNAHzzzdcsXnwqNptN\n+jmj0cipp87km2/EdihBEIYO315tiCZY+q/NaWN17hoA1Aq1dI3v64vSzgUgqHnrUOt5Z2/A7UiT\noyXZyOfNXwqOR76xEIDU0BS/9y8ftYSloy5mfsIcv/ejtJEk6lpSJBsCI5gWPem423GsBn4p3CD1\n1FPP8+9/PwhAUlKyVONYpXJy/vkXMHPmLACCg0PYsmUT8+cvAOCnn9YTFRU9IG0WBEHoKd+5YqvT\n08kIVnvqEawr3AiA2iewegNyREAYAc094MDmFdmttxy1N6fry3fuOLsul3xjIUn6hB7P3Vqdns/X\nqfxTGmsUar891b5UChWPzLmPA9WHmBk7dUBycose8jEKDQ0lIiKS6upqAGbNmsPatd9J59evX8u0\naf2T1UUQBKG31Pgsdpoe4+kdKlv1bDU+vWLva99A7g3S3oDutd9nRfMru9+monlIGTy1h032JhJ1\ncdJ7j29/gd/KMukp7+f7Dqt3R4hGz6y4aQNWIGNQ95A/z1nNzoq9vXrPSVHjpeGVnigqKsJorJd6\nwenpo1m5cgVNTSYsFgt2u53w8P5fDCAIgtBTBQ1FZNXkAPDEvH9KVZEUcv8+m16tk17PiJlCvrGQ\niMCW33feIG1zeQKi0+Ukuy6X7Lpc6Zp91QfZV32QR+fej16tw+q04nQ7CdYE86/xV3P/lkcB2F21\nnxmxU3r0PN4esu8XiKFgUAfkwaKgIJ9bbvkjADqdln/8458olS1/dLNnz2Hjxh8xmRo55ZRTaWgY\n+sXNBUE4OdRYanl82wu4cRMVGOlXotB3dTW0DGEDzE+YTagmhGCfIO2dK7Y1Z8H6Kvdb1hVsbPdz\n1xVs5MK0szE1F6sIUmmJCAznxgnX8uqe5Vh9hr3LmyrRKgMJUGhQKTqfj4aWIfOuFpMNNoM6IF+U\ndu5x9WZ7oqGhgYCAAFQqFS6XC4VC4TeH3DqXNcCCBYtYvvwNTCYT9933L1av/qpf2ywIgtBTFU1V\nuPEE3gvTzvY752y1BSlKa/A7bp0m09sj/bl4Cw22Bo7Wt62k5OUdVjY5PAvAgpSe+d7xkWNQy1U0\nNa/UPlCRzb9+fRqAEaHDuWPyjZ0+z7sHPmJHxe7m9gytgCzmkFt5+unH2LhxA263m4KCPKZPn9Xl\nz4wePZayslKcTifR0TH90EpBEITeUWetB+DKUb8nwzDO75y7VUBOD+u8Pr3vyutdlfvQqYOkY985\nYmgp/NDk00P20qq0Us85r65Qej+7LtevNGJrOXVH2Vq2A4AQtZ4AEZCHtuuv/yMff/wBf/7zMmbO\nnNPtyf3p02cxb978Pm6dIAhC76q1eAKyd++xL98Ba50qqMvfh63nbIt9SjNOa7Wvt655EZl3i5Rv\nQA4PCKPWWke9tcFvCB1gf9XBDj8/u7Zlrnp4aMqALc7qqUE9ZD0QEhOTeO21t/3ee/PNFe1ee/bZ\n50mvb775dun1smV/6pvGCYIg9DJvYGw3IPvMIUdpI7u8l1qhJkillTJl+UrSt+zzDVQGkl2Xy32b\n/8OC5j3BvuUPp0RnkFufx7byTMKCPXPUkwzj2Vm5l7pOqi8F+QTv05OGXgdJ9JAFQRBOQi63i1f3\nvM0vJVsBCAtoG5B9+8iGwK4DMsCosBFt3vvbtDsYEZZKSnAyAIuag2WNpZZco2ee2ZvlCzw5ppUy\nBVtLd5BX56m37E1W4l1B3R7vcPbVoy8lOTixW+0dTEQPWRAE4SRUZa5mb/Pwb4g6mEBlYJtrXD4B\neVbs1G7d9/zUs6RFVV7eBB23TfojZoeFYLWOanMNm0t/I6d5S5RvD1ynCiI1NIWs2hxKcsukNgJY\nOg3IntXdwRp9h9cMZqKHLAiCcJLIrc8jtz6fequRIp/5XW8ga807ZK2UKxkRltqtz4hszmvty1tL\nWK1QEaLRI5PJSNB7Fnk12BpRK9RthsyDmwOwV3hgGAAljWWsyVsvLQbzcrqcUg+5q1Sdg5XoIQuC\nIJyAyhoqKGmoIdFn7vapHS8DoJApcLqd0vuToiZ0ei/f/cfdcdawRWwo/EWq7qSUt60nnBKSJL2O\n1hraLMDyJhcBz9x0st4zBO1NLJJZsYe/T78DgKKGEv6z7VmpApVvJaqhZGi2WhAEQejUbd88AMBL\nCx8HYGPRFumcbzBeNm4pYyNGtXsPV3MPWcaxrVY+d/gZnJ2yiFs3/A0ApaxtqPEt5hDdan8ztOxL\nXjziVM6IW4Tb7UYpV0p5sYsaW6pC7azYAyB6yIIgCMLg4rs6usxUTlbtET4+/KXfNcnBiZybcgZj\nItI7uxPAMYZjD7msZUZU0U4P2bdHHNXOgrEL0s4iUR/HBRmLqK32rNo+Z9jpfJX7bZtrW2fvEgH5\nBFJaWsLVV19GevooZDIZNpuNm266nYyMiQA8/vi/OXBgP8uXr5R+xuFw8Prrr/Dbb1sICAhEpVJx\n++13kZra+UZ6QRCE3uZbzvDNfe9TYiprc82c2OldBGNP+cJt5TsZHzmmR+24fuwVVDRV+QXn9mhb\nVWUCz8KuUxJm+w13z0+c4xeQb15/N9eNvcIvAI8MS+tgxfjgJwJyB3zTZe7alck777zB00+/iN1u\nZ9Omn1Gr1eTn55GcPAyAlSvfpbGxgbfeeh+ZTMbevbu55567eP/9T/3yXguCIPS1anON9Lp1MD5r\n2GnUW41Mi+m63u+cuOnEBcWQHJzQo3ZMiZ7Y6fmp0RPZXr6L1NBh3bqfRqHmsXkP8MGhz9lV6Sk8\n9Pb+lVwy8kLpmtsn/bFHbR0MRKTohpqaGiIjPXMcP//8MyNHppOWNpIfflgjJQH58svPeOedD6Vh\nmPHjM3jjjRUiGAuC0O+qLbXtvu+tsNRdcpm828GyJ5aOupizU05vdw65IzpVEPG6GCkgQ0u95TOT\nF/Z6G/vToI4WlZ98SMP2bb16T/3UaRguvqzL67wVnmw2G1VVlTz11AsArF69mtNOO4ORI9O59967\nWbbsTzQ2NqJWa9Dr/Vcitj4WBEHoD9WWmjbvnTf8zGMKxv1BpVAdUzD2igz0L3H7ec5qANJCU3ql\nXQNlUAfkgeQ7ZJ2fn8d99/2Vl19+k02bNnH77Xej1QahVqvJyjpEfHwCLpezizsKgiD0j6KGEr/j\npaMv6XZij6Ggo6xhQ3Uxl9egDsiGiy/rVm+2ryUnD0Oj0fDZZx/hdDq56aYbAKirq2PdujXcdNPt\nOBwOamqqCQ9v+eaWlXWIkSPTh1yCc0EQhras2hy/40mtqjgNdTFB7feqWxeiGGpEpq5uMBrrqa6u\nZs+e3Tz++OMsX76S5ctX8uqrb7FhwzrcbjdLllzC888/jcPhmcvYs2cXjzzyIDabrYu7C4Ig9C6z\nw0JSSMs+3wBlwAC2pve1l+YTIEYb1c8t6V2Duoc8kLxzyAA2m40bbvgzr7/+Cqeccgq1tZ4tBbGx\nccTFxbN3726uuOJq3n33La6//kqCg0PQ6XQ8+ujTaDRDqx6nIAhDmyeFpB29Joip0ROJDYoe6Cb1\niTBNKLXNlarAk52rvf3OQ4kIyO2IjY1j7dqNbd4/66xz26yafu65V6TX11yzjGuuWdbn7RMEQeiI\n1ekZlQtUBnDdqCsGuDV95/+m3sLOir2sProGs8NCXFDsQDfpuImALAiCcALxlicMVJ1Yw9SthWiC\nOTVxDhmGsXyQ9TkXj7hgoJt03ERAFgRBOIF4yxMGKE+O6bKwgFBuyrh+oJvRK8SiLkEQhCHEW0Ch\n4/OeUopqhbo/miP0ItFDFgRBGCJ2Vezl9X0rAE/GqmitgevHXelXS9jRnBNBpRC/3oeabvWQDx8+\nzKJFi3jvvfcAKC0t5aqrruKKK67g9ttvl7b2rFq1iiVLlnDxxRfzySef9F2rBUEQTkIbin6RXjfa\nTRypz2N/9SG/axzNPWTlEK0JfDLrMiA3NTXx0EMPMWvWLOm9559/niuuuIKVK1eSnJzMp59+SlNT\nEy+99BLLly9nxYoVvPPOO9TV1XVyZ0EQBOFYNNgaCVQGsiBhrvReeVOl3zV2bw9ZBOQhp8uArFar\nef3114mKatlwvXXrVk477TQAFixYwJYtW9i9ezfjx49Hr9cTEBDA5MmTyczM7LuW97HCwgL+7/9u\n54Ybrub665fyzDOPiyQfgiAMKKOtkVBNML8feT4PzLwbgCa72e8ab6GF1jWChcGvy69QSqWyzd5b\ns9mMWu1ZMBAREUFlZSVVVVWEh4dL14SHh1NZ6f/NrbWwMC1K5eDbyO10Orn++r9x3333MX36dNxu\nNw8//DAff/wuf/nLXzAYToyiEeI5BhfxHIPHYHyGAxWHMTvMjDKkYjDoUVvcALgVTgwGPY1WE+/v\n+ZKE4BjA00MejM/REyfLcxz3mIbb7T6m933V1jYd78f3iV9/3Ux8fBIpKaOprGwA4LrrbkTWXGTb\n+95QZjDoxXMMIuI5Bo/B+AwWh5XHNnuSEE2OmEhlZQM2p6cnXN/USGVlA59lf836wpY5ZpVCOeie\noycG499HT3ifo7Og3KOArNVqsVgsBAQEUF5eTlRUFFFRUVRVVUnXVFRUMHFi58Wpu7J5/RFyD1Uc\n1z1aGz4qitkLUzu9pqAgjxEjRvq9p9Gc2JvsBUEYvIy2BswOC+MjRzM5agLg6QHLZXIsDitlpoo2\ni7vEoq6hp0f7kGfPns2aNWsA+P7775k3bx4ZGRns3bsXo9GIyWQiMzOTqVOHarkvGS6Xa6AbIQiC\nAMCuyr2Afx1gmUxGgEKDxWnhoa1PtlncpZCLNBNDTZdfofbt28djjz1GcXExSqWSNWvW8OSTT/K3\nv/2Njz76iLi4OC688EJUKhV33nkny5YtQyaTcfPNN6PXH9+4/+yFqV32ZvtCcvIwPvvsY7/3bDYb\nRUUFGAyT+r09giCcfOqtRhQyBTp1EF8d+RYAo9V/6NbitNJkKpeOQ9R6Lko7l1W53zE8LBks/dpk\n4Th1GZDHjRvHihUr2rz/9ttvt3lv8eLFLF68uHdaNoCmTZvByy8/xy+/bGTu3FNwuVy88soLaLVa\nZswQAVkQhL5VZa7hgS2PAjAjZor0fpPDf0W1y+0/knfH5BuJ0hqYGjMJg15PpWXoz72eTMQkQzvk\ncjlPPfUijz/+b95++3VUKhXTps3guutuGOimCYJwEngms6WK3NayHdLrcZGj/a4LDwijxlIrHUdp\nDX3fOKHPiIDcgcjISB5//JmBboYgCCehOmt9m/cSdHHMj5/t996dU27i3k3/7q9mCX1MzPoLgiAM\nAWMi0pHJZH7vhWpCeGLePz3nw9MHollCLxI9ZEEQhEHC6XLy+PYXpOPfjzifT7NXATA9ZnK7P6NV\nBfLCgkeRIWv3vDB0iB6yIAjCIFHUWEJRYwkAN4y7ivkJswlUBhCjjSI2KLrDn5PL5G16z8LQI3rI\ngiAIg8Dmkm28f8hTJS81ZBgTo8YD8PDse1HIRN/pZCD+lgVBEI6Ry+3C7rR3eo3D5ehWCmEAm9PG\nR4e/kI4XDztNeh2g1IhCEScJEZAFQRgSCoxFPL79hXZXIPe3t/ev5MFfH++wLfnGQu7Z9DAfHf6y\nW/fLrjsqVWkC0KmCeqWdwtAiArIgCEPCS7vfJN9YyPf5Pw5oO6xOG5kVe6iz1vP2/pVSL9jldmF1\n2jA7LLyw6w1M9ia2lu3g+7wN5BsLO72n0WoEPKumg9V6ooOiOr1eODGJOWRBEIYEi9MKeAKfxWEh\nQDkwBV9y6o76vS5rqiA2KJrPs1ezoegX5ifMxtycUcvmtPFV7reQCy8tfLzDezbYGwG4PP2iNsk/\nhJOH6CELgjAkeId0fy7ewp0b7x+QNhQYi9jdXOghLshTd/iz7K8B2FDkKX34U9FmgDbbkLw96fbm\nlb05qvVqXR+0WhgqREAWBGFIUMgUfsc/F2/hw6wvsPvMvfa1x7Y/z6aS3wA4K2URAI22RqxOW5tr\n/zBuqd9xUWMJz+/8L3dtfIByk39Z2Qqzp3Stwaeak3DyEQFZEIQhwaCN9Dv+MOsLfi7ewvaynQPS\nnrERowAobCzhxV1v+J2bGj2RMRHpTItuKUbz/qFPyarNweK08K+tT0o9fpvTTl59ASHqYLQqbf89\ngDDoiIAsCMKgVmet579736XKXE2Qsm3Ayq7L7Zd2OF1O6XVqyDA0CrV0nFuf53dtXFAMaoWaa8de\nzhnJCwAobCj2u+arI9/icrt4cMtjmBxNzIwdqvXjhd4iFnUJgjCovbH3PY4a8wEIVQfz+CkPsrfq\nAK/uWQ7AkVbBsK/YXZ59x2PC0/lzxnXtXpOoj2dJ2rmkhqZI73U0L7y+8GcMgRHU2zwrrOfFz+zl\nFgtDjeghC4IwKJWZyrl5/d1SMAaostQAMD5yDH+fdgcpwclUmavZXr6rz9vjnavWKNTImzNnXZR2\nrnT+svTf8afx1zAiLFU6D6BVBkqvW6e//OLINwDMT5hNWEBon7VdGBpED1kQhEFp9dG1nZ5P0MeR\nFJzAUWM+xY2lTI2e2Kft8c75KuUtWbNOSzqFJH08NZY6ZsROaffnRoSmEqON4ndp5zAqfARr8tYz\nOmIkT+14GVvzYjBRqUkAEZAFQRikNHLPHG28LpabMq7n5d1vMSFyjN81M2Im81PRJr/53b7iHbJW\nyf1/bY4IS+305yICw7hv5l3S8TnDz2iz9Sm2eQuVcHITAVkQhEHJ7LQAcOvEG9Crddwz/S9trlE2\nB0e7y47L7aLJYe6ztJPeIWuV4vh/bcpkMsaEp3OgJgulTEFYQMhx31MY+kRAFgRhUGqyNwH+c7Ct\nqZqHj61OG7du+BvgmY89PelUvznZ7WU7+aVkK9eOvZxQTc+Cn7eHrJT3zq/NUlM5QJs5Z+HkJf4V\nCIIwKJnsTQQoAlDIFR1eo26uglTRVCm991PRZp7c8ZLfdW8f+IDsulz+l9v5vHRn6przTetVvZNN\ny7vAa3rM5F65nzD0iR6yIAiDTkljGSWmMik9ZUe8PeSjxgK/91tXYYrSRlLRVMXh2hyezXyVc4ef\nSVpoCodqssk3FnLmsIVt7u1wOfileCsGbSQv735Tej9aa+jpY/lZOvoScupymRw1oVfuJwx9IiAL\ngtBn3G43OXVHyarNxul28WPRJq4efSnDghPZV32IuXEzkMn8cz7n1B3lmcxXALqseqSSd7NOcPMa\nqipLDVWWGp7JfAWlTIHD7VkMNi9+ZpssWd/lrePbvHVtbtVbATlEo2dKdEav3Es4MYiALAhCn8mq\nzeGFXa/7vffGvhVMMoxnZ+VeYrQGRoSlUtRQQoW5iomGcVIwBrgw9exO7996xXNHzA4LwWo9RluD\n9J43GAPYXHZa5wA7UpfX7r0iRb5poY+IgCwIQq9zupx8nbuGHwp+avf8zuaKSbn1+YwIS+XNfe9R\nYa4iNWSYdE1kQDiRgeGdfo5MJuPclDNZfXQNAL8fcT6fZq8iRB2M2WEmUBmIzWnD5GgiWZ/gF5B9\n2Z1tC1TUWOuk13FBMUyJnkhaaEqnc9qCcDzEoi5BEHrd3uqDrC34EXfzWPFpSacAEKzW+1131FiA\n1WmTqh35psHsbr3js1JOk14n6OLQq3TU24zctfEBsmtz2Vd9CJfbxciwNMI0npXXF6SexUVp5zI7\ndjoAPxT+xL2b/k2txROE660NVJmrAU8Zxb9Pv4PFwxaS5pMSUxB6m+ghC4LQq5rsZv6X+710nBE5\nlnNTziQyIIKZsVN5dNuzlDdVEqAIIK++gMO1OW3uMSFyLPMTZh/zZyvlSmbHTWdN/noAnt35qnRu\nSnQG8+Jnsq18J4uS5iOXyaVaxr8U/wp45q9HJiZKxSLOHraIRcmnim1JQr8QAVkQhF7jdDl5dNtz\nVDfnnAaQyxWoFSpOSZgFwJ1TbqbKXM3agp/YWbGHguYqSHFBMZSYygD404Rrjulzb8pYxo7yXSTp\n40kJSWJ85Bie3PGi3zVxQTHIZDKp+hKAutWisOUHPgCNgzqzCfAUi/Ct6iQIfUl87RMEodfk1xX7\nBWOA+KBYv+MglZbk4ESS9Qme2fm5AAAgAElEQVQAHKk7CnSdgrIzYyPSuXrMpdL8bkpIEleO+r10\n/vSkU9us5gZQKdqu0j5YmYOpOSmJTt03Wb8EoT0iIAuC0GuKjWV+xxemns0Zyae2e22IJhjwrMQG\niNF6tjjJaBs4e2Ja9CQAQjUhXJjW/mpt35TSd0+9FRky6i1GKSC3V39ZEPqKGLIWBKHXrM76we94\nQeLcDlclaxQav+NhwYn8cfzVxLXqUfeUSqHikTn/aLdn7JWojwM8pROTgxPRqYKotzSgwjNMHSR6\nyEI/EgFZEIRec7SuEICbM5Zhd9k7zfucHJzgdxylNZDU6r3j5e2Fd2Rc5Giemf8w6uZ5Yr1aR621\nDovdhl6tEz1koV+JgCwIQq+wOKyAJ3HGmIiu6/uGakK4c8pNfHP0BwyBEQQoNV3+TF9Q+yzaClbr\nKTGVYcbCyLC0TnvXgtDbREAWBKFXeJNuHMte3eEhw7hl4h/6qknHTK9uKRxR3lyNSRD6i1jUJQhC\nr/ixaBPQsjhrKBofOUZ6fUZy24ITgtCXRA9ZEITjZnPa2Fi0mVhdFPMT5gx0c3psSnQGc0dOorrK\nNGBD6MLJq0cB2WQy8de//pX6+nrsdjs333wzBoOBBx98EID09HT++c9/9mY7BUEYxGqt9bhxM8qQ\nJtUoHqp06iDMKtdAN0M4CfUoIH/xxRekpKRw5513Ul5ezjXXXIPBYOCee+5hwoQJ3Hnnnfz000/M\nnz+/t9srCMIgVN9cfzgsMGSAWyIIQ1eP5pDDwsKoq/MkYTcajYSGhlJcXMyECZ5C2wsWLGDLli29\n10pBEAa1yuZCDFFBojThiaC2ysSWDUdwOsVIQX/qUUA+55xzKCkp4fTTT2fp0qXcfffdBAe37PeL\niIigsrKy1xopCMLgVm7y/P+eENw7ST2EgbN7WyEfvrGNXVsLKcqrHejmnFR6NGT91VdfERcXx5tv\nvsmhQ4e4+eab0etbyqq5ffPRdSIsTItSOfRqixoM+q4vGgLEcwwuQ/U5KkzVVNg8W4TCtaFEaofm\nc/gaqn8XrfXkObb/kie9djsHx5/FYGhDb+jqOXoUkDMzM5k7dy4Ao0aNwmq14nC0FPguLy8nKqrr\nrQ+1tU09+fgBZTDoqaxsv8j5UCKeY3AZqs9xpC6PpzNflo71at2QfA5fQ/XvorWePodWp8Fm9fxu\n3rElj+QR4QOaIOVE+/voLCj3aMg6OTmZ3bt3A1BcXExQUBCpqals374dgO+//5558+b15NaCIAwB\n2bW5fJ27hk0lW/3e1yhFqcKhzGK2U1fdREy8ZwqyorSB3KyqAW7VyaNHPeRLL72Ue+65h6VLl+Jw\nOHjwwQcxGAzcf//9uFwuMjIymD372IuLC4IwNHx4+AvKWmWyClCIfbtDmbHOzM5fCwAYnm6grNgI\nQHmJkdRRhoFs2kmjRwE5KCiI5557rs37K1euPO4GCYIw+JlsJgAUMgWLhy0kIiCcYSFJA9wqoafM\nTTbef9Uz2qHVqRk7KY5wQxCrP9qDy+W/0tpuc1BWbCT3cBXzTk9DLhcJH3uLyNQlCMIxcbqcONwO\nIgPCeWDW3chl4hfyYHQkq5Lc7AomTEtELu98DrikoF56PXF6IkqVgogoT17vRqOnaMjGNYex2Rxk\n76+Qrk0fF01MvNh73ltEQBYE4ZgcrDmM2WFhavQkEYwHKbfbzQdvbsXldGOI0ROfHNbp9SUFLdub\nxk+NByBQq0KhkEkBef/OkjY/Z2qw9mKrBRGQBUE4Jr+VZQIwK3bqALdE6EhtVRMup2f7aXFBHW43\nBOnV1NeaSU6N8Fs17Xa7Obi7FIALrpwoDUHLZDJ0wQE0Nlg6/JyGek9ALs6vxdRoY+TY6L56pJOC\nCMiCIByTSnM1KrmKJH3CQDflhPbLD9kc2lOG3eZkyTWTiYoN7vqHmm1alyO93rEpnx3kS8f6kAB+\nd9UkgnQadm8rpLSwHqfTTXxyKHGJoX73CdJrqC8wY7c5AYhJCCY2IRSZDDK3FNBotOB0ulj1gWfX\nzfCRkShVQy+3xGAhxpsEQTgmVqeVAIVmQPemngwO7i6VAuEPqw52++dcLhdlRfUdnm+ot/Dui1vY\nt6OYzeuOcPSwZ1vTxBmJba7VBXtWzldVNAIQEKhi5qnDmTDN82Ws0WglL7tlW5SxvuPetNA1EZAF\nQTgmVqcNjShN2KecThcOe8/ySBvrLDgcLpJTO88r/vPabL/jpOFtr1erPYOoX7630+9YE+Cp6HU0\nu4rvvzwgXd9oPDECck2Vifdf/ZWSgrp+/VwRkAVBOCYWhxWNQiQA6UtWi8PvOD7ZM5R8aE8pP605\njNvtpr62qd00xdLwclzbIW61RolW1/bvLjg0oN12uFrdXxfi+SIml8tQqtqGD3OTvd37DDV7txdh\nrLPw1cpdbbZ99SUxhywIQre53W5pyFroO94EHRGGIKorTSCTYW6yseGbLMCzujk/p5r0cdHMPysd\nhaIlODocngCiVCs477IJBGrVHNhVSk2VifMuy8BitlOQW0Ph0RpyDlRw4ZUTCYsMarcdbpd/QPbd\n4qRWK3HYbX7nLSdIQHY6WoLwzi0FTJkzrF8+VwRkQRC6zeay48Ythqz7WGmhZ6g0fXwMm9cfwdJk\nY/nzm6Xz+TmecpdZ+8rR6jXMnD9cOucNJiqVgoRh4QDMO2OEdF4bpGbU+BhGjIlizsJUtLqO/y5b\n98CThodLr1VqBZj8r9/5awHD0w3oQ9rvcQ8Vdp/pgqK82n4LyGLIWhCEbrM6PdtcNKKH3GfcbjcN\nRishYYGkjfEU6amvMbe5Tq3xrGb2Bmcvh8MzZK1Udv7rXaGQdxqMPY1peTlshP92KZW6ZTW1IcZT\nMMHcZOe9V37FbvMfcm9ssPLxm9s6XWxmarDSMEgWhXn/DBVKOQ3G/ttrLQKyIAjdZnF4fjmJIeu+\n4Xa7+WHVASxNdiKjdVJQra70dEVHZ8Ry+gVjSEoN56KrpwBQU2nC5XLhdrspK66XEnn0Rmlb3x7y\n2EnxfueS01oWgZ1x4RjSRrfku64o9a/OtD+zmOpKE1++v7Pdz6mraWLFy1v49J0dvT5nW1nWQH1t\nE4f2lOJ0+t+7rLiesuK2XxK8C+pi4oNpNFpwubpXUvh4iSFrQRC6zdtDFgG5b1RXNJJzsBKAmacO\n95sbBk+vN210FGmj/cvbfvPJXiKidOzaWthybTuLro6VNwzJZP7D1QDT56UwaUYSSpUcmUzG6ReM\nJSahiF/W5lBfZ/bLDhbU3BNvZw0aAL9tPIrb7ZmDPrS3jDEZccfddoDD+8pYt/qQdLx/ZwlLrpki\nHX+xwvMF4brb5xAQqJLed9idKJRy5ixKo6bS1GXq0d4iesiCIHSb1elZxCNWWfc+m9UhlTqcMjuZ\n4NBAFEo5ckVLMMiY3navMEDh0Vq/YNxrmgNoR3PCKrXCbxg7JEwLgNnUanFXF/GsvMQovS7J752t\nRrlZlX7BGPx77r69/yOHKvyus9udKJVyIgw6Rozpv+xjIiALgtBtFodnjk8s6updVoudT97ezo7N\nnoxasYme1cwymYykFE/PNEivaRMYW/eUffXGfGyA1tNr1AV3b5GWd17bZvWfQ7bbndLrJpP/ymyX\ny0Wj0UpMQghqjaLNcHdPrflif5v3IqM9BTOcDpffl4CyYiMVpcbm9rgxm+x+c+T9RQxZC4LQbebm\ngByoHNqraAebwqO1GOtaAmigtmUEYt4ZI6ivNTN5dnKbn1t47ijGTorjq5W7ABg5NpqJMxPZvO4I\nU2cPo8lia/Mzx2LqnGRwQ8b07qVJ1QR4QopvQLbbnPy6IVc6rqlsRBvUMvzt7U0H6dSo1CEU5tbw\n28ajTD8lpcfttlpaeugqtYLElHDKS+ql/d07txaw7ec86ZrD+8o5vK+ciTMSOXq4CovZzqi0mB5/\nfk+JHrIgCN3W5PCs9tUqtQPckhNL696sb09YFxzAZTdMb7dwg0IhxxCrl45PPTudCIOO8y7LIEh/\n/KMYmgAVcxalHUMP2ROQTQ02aftVdWWj3zXr/5eFxdwSML09Zm2Q2vMFANixOZ+C3Joet7u6wrMI\nbsLUBJb9ZS5nXDgGTYAKs8lGk8lG9v5y6dqQsEDp9a6thdTXev6NJ6X6z5n3BxGQhW5xupzc88tD\nvH/w04FuijCAmuxNAGhVgV1cKRyLhuaUk0uumcz1d8yReprdoVIpmL0wlbOWjGuzCKy/edudf6Sa\nD9/4jeqKRtZ+dcDvGlODlRUvb5ECtqnRs1BQq1MTEx/C8PRIACpLjfSUdzg6NjEEmUyGTCZj5Lho\nHA4Xv6zNxtlcCWveGSO44k8zuPyP09vcY9iIyB5/fk+JgCxI9lcfIs9Y0Ob9L3O+4d7N/6be1sDm\n0t8GoGXCQMquPcLXuWv4rSwTk6M5ICtFQO5IaVE9mVvy201r2R6H3SntMw4JC5TyRB+LjOmJAxJA\nWlMqFUREebJ+GessbPgmS9qG5cthd5F90LOQqqmxuYfcvBJ7RnOSE29P9Vg4HE5++i5LKifpO9Iw\ncXoiWp2aI4cqaai3EBWrZ9xkz1au0HAtk2clSddefN2UAflyI+aQBQBKTeW8vPstAJ485V/SHGGd\ntZ61BT/6XZtbn4/T5aTWWsfU6ImiSP0JzOKw8OzO16RjpdzzKyMisP+H84YKbyGGksJ65ixM7TAt\nJXhW+n74xjYa6i2oNUppyHcoi4zWS0PGgdqWLxfTT0nht41HpeMN/ztEaUEdQc0VpYKac2zrQwKQ\nyaC+riUgN5lsyGSeIfT2tiBZzHa++3wfwSEBZO1rGY7WBrXMxctkMoJDA6QvAL5D1QBpY6LI3FIg\nPcNAGPp/+0Kv2FS8VXp9qCabSVHjASgzVbS59qkdL0mvG22NLEw6pc/aVWetZ03eBk5NmE10UMcr\nSoXes6dyP98cXcv1465k1ZHv/M45XA4MgRHoVB0HmZOBw+FEoZD7bflxudw4fFYTF+bWsMntZvKs\nZEIjtH7Bwcs3O9W8M0acECUtM6YlkLW3DPAPiJHROoanG8jNqpTeO7S3jLikUL9rFQo5+pAA6qrN\nuN1uCo/W8M6LnrSh009JYUo7i9v2bCuitLCe0sKWJB9yuYzAVn/mk2YmseGbLBKSQ5mzKM3vXHhk\nEOMmx/ntn+5vIiCfxA7X5vBp9tfUWuqkxToA3+b9QEpIEqGaEOqtnrmYy9MvIiYommcyX/G7xzd5\n6whUaZkVO7XX2+d0Obl3078BqLfW88cJ1+Byu0SPvA/tqdzPa3vfAeDZzNeot7Wdxztv+OL+btag\nYqwz8+nyHaSMjGTB2aOk97f9fFTqYXkV5dVSeLSWwCAV1946B4fdSVFeLW63J9NVeYlni8/UucPa\nXbQ1FEVE6UhODSf/SA2HmgPzuZdOIGFYGIkpYTgdo/j2s70UN+839s73+lahiooLJudABXXVTZTk\ntwTZ3zYeZcrsZCxmO2qNEpnM0/Ntb5/zJcumtulND0uL5Lrb2h/al8lkzDtj5HE9+/ESAfkk9lvZ\nToobS6Xj+2f+H//69QmKG0t5cvtL/HPWXzlYcxiAEE0wKcEtcyxL0s7ls5zVWBwWPj78JZuKt2J2\nWvjbtNtRyXvnn5XR1rIfcXfVfgobinl6x8ssGXEec+Nn8kPBT8SbDIS4w4nTxfB17hrkMjnnpJze\nK59/Iik3VRAWEIZa0fH8ZK2ljhUHP5aOfYPxnydch1KupMZSy+SoCX3a1sHMWGfmwK5SrBYHh/aU\nMTojVqqA5BuMR2fEUl9rlurpmk12mhqtfPD6b9isnl50XGIIkc05oKPjBmaItK/MmD8ctUZJ9gHP\nCFtktE5aXCVXw/mXTyQ3q5I1X+zH6XCh1ij9MmXFJ4WSc6CC4oI6tD5bwBRKOYVHa1j90R4SU8Io\nPFrL/MUj28z3/u6qSYRFDL1RHBGQT0Iut4u3Mj9iS+k26b0ZMVOI1hqYFDWBnRV7qLXW8X3+BnZU\n7CY8IIyRYWko5Ar+OetvKOUKQjUhLEw6hf/ufZfdlfs4avQkNKgyVxMb1Dvf9L1ZobzWFWzE5rLz\nQdbnpIQk80XO/yDHc+6h2X/nu7x1ACIgt5JTd1Qa2QhUBvCfufejkitxupx8eeQbMgzjSAtN4du8\nH/xGSrzunf7/iNP1/57MwejL93Ziamz5d7n6oz1ce+vsNrmOYxJCCI8M8itwv31zvhSMwTPHXNI8\nxNrecPZQFhGlY9H5Y6SA3F5ebd9c2IkpYX7D9d76zz9/ny29p9YosFmdrP5oD+DZuw3w03eHpeIW\n0rXqoRnaxNjfSaCwoYQPDn2GzenZ+1dmquC77B+l86cnncpFaecCnqHpK9KXALD66Pe43C5+l3aO\nlCoxMjCcUE1LTdSRoal+n1Vn7biay7GytQrIufV50utHfnvG75xvTx88z/zotufIN/ZBOsEhZkf5\nbum12WHhveZe8M6KPawv/JlnMl/B7LBQ3OgZXrw8/SIAIgMjeGTOfSIYN3O73VIw1urUJAwLw25z\n8vpTP/PmM79I142ZGEv6uGjCIv33avvOnQJ+w6kB2hMrILfWXl5thUIuvR8dF+x3Ljg0sM2XlIxp\n7acNBU8BCfAEcrVGgS54aGaSG5pfI4Rj8ui2ZwH4pWQrN4y/2m+h1hnJC7gg9SzpOEilZU78DD48\n/AUut2ef4LiIUXTklIRZJOjjKGks46PDX0hzzr3BW8jAq9pS2+G13mAC8Mrut9hX7clhu7nkN5KD\nO/4f+URXbzWyrXwnKrmKe6f/Px789TEyK/YwL34Wn2Svkq67a+P9AERpI5kbP5O58TMHqsmDlqN5\n32yQXs05F0/g0J4yivL8/03GJYYwf3E64Oklp4024HC4yMuu9svvHB0fjEqlkH4+MPDYtzoNBRdd\nPRlTg7XDxWpnLRnPvsxiRmfE+r0vk8kIjdBKSUMmzkgkcXg4237J6/CzIqKCOO+yDFxON4ouSk8O\nVkOz1UK3/S/3e7/j1/e+y9e5npWz14y5zC8Y+7o5Y5n0Wt1JIQG5TE5aaArBmuZ6qI7eq2ea31AE\nwPCQYe2eT9C1VITx/ZLhDca93Z7BbnvZTv699WmKG0txupzk1udzz6aHMTvMZBjGYtBGcPGIC3C5\nXTyT+QqNdlOb/cQiA1fH7DbPcHN0XAgRUTpmzG+b2tE3/7FKpeD0C8a26dlNnTuMxReNo77Gs6c7\nMlo3ZANIV6LjghmebujwfMKwMBZfNK7d7V6TZyWhDVJz0ZWTmbUgFV0Xmcei44KRyWRD+s9S9JBP\nYEZbA9/k/dDh+YmG8R2ei9d5vrFmRI7t1mdpm/ctezM59YYvcv4H+Jf6m58whwZbA7PjpqOWq3k6\n82UA9lb5ZwMaFzGKfdWHKGo1lD2Y7Ks6yObSbeyu3Mf9p96BzKImStuz5A4ut4u3D3wAtB3Oj9fF\nctXoSwCYETuZrWXbKWgoJkQdzMKkedKfM9DhFzQBaUuTqnmYValS8LurJmE1O9i8Poe6GjO6dqoi\nxSWF8rurJnF4XzmR0TrGTPR8kUwbE83OXwvaDewCJKaEc82tszEY9FRWNhCk1xCfHEpxfh1KpVwa\nsQgODcAQo293O9RQIwLyCarB1si7Bz4CPAHthvFXkxKSTHlTBUUNJaREx3W64lav1vHo3Pu7XUQg\nsLmn1Rs90nqrkRd3vSEdXzn69zy/87+UN1USr4thTtwF0rkVS55j2Rd3YXH6f+5l6Rfx7sGPOVyb\nQ5PdPOhSPbrdbl7Z87Z0/K8fPdMK/5z1NyJ7kHTDuxq+tRGhw7l27OVSQo9AZSB/nXa7dL7RZpIC\n8ksLHz/mzz2ZeHvIvr1g7wrrxOFhlBTUS1mqWouJD5Gu9Zo6N5lRE2IIDRejEt218NzR/LI2mzET\nY/nfx3uRy2VceeOJM70iAvIJyOV28cKu1yluLGVMRDp/GHeVtCgrSZ9Akj5B+tbZGb1a1+3P9A59\ntrdK91jlGQspMXnmhEPUekI1Ifxt2h3srdrP+MgxftdqlGoyDOPZVp7p936IJphhwYkcrs0hv6GQ\n0eEDu7+wNd8tXb52Ve5lUdL8Dn+uuLGU7/M3cHrSqSToW4bs91f7131VyZU8Me+fqDr50gWgUwex\nbNxSorUdDyuerKorGvnfJ3tZdN5o4pJCpQpGqnZW8MrlchKGHVtCCaVSIYLxMdLpNSy+aBwAl/1h\nmt/e5RPB0B1sFwCwuxxttgetOvKdtOr4zxOu65di8t4ecoOtkS9zvqGoocTvvMneREVTZXs/2obJ\nZ9hbKfcEFLVCxZToie3OZ48OHyG9XjZuKXdNuQW5TM6w5n3TefX9u9LaaGvg+/wNOF3ODq/x/lm0\n3tN7sLr9nq7X5pLf2F6+i/9sexajrYFGu4kGWyO/lm4H4K9Tb+PSkRfy9PyHuwzGXpOjJkhTFEKL\ndasPYmqw8tXKXXz+bqa0zSY4TJSeHAzCIoN6lPd7MBM95CHuie0vUNxYyosLHkMmk9FkN/vlnu6v\nrFYBSg0yZByoyeJATRY/FPzE8wv+w6oj36FVBfLVkW8BeP7U/6CQd1z4u8HWyMeHvwQgTBPKtWMv\n7/Kzp8VM4pujazHaGhgXMUoK2t6AnGvMO86nOzbv7P+QQ7XZrDryHUtGnEda6HASfXqzBQ1FvNSc\nN3xMxCgUMgXbyj35j8uaKnC6nCjkCoobS4nWGqThZvAfgfj7Lw+1+eyk4ASSgrtXu1boWF1Nk5SP\nGTzZpLwZpcI7yU0tCMdDBOReVGOppcHW2K/bbLw94TX5G1iUdEqb1Jb9RS6TE6AMwNwcMNy42V99\nqE1hCqvTilbe8TDda3uWY3d5tofcMP6qbv1ZymVy7p1xJ02OJr8edIhGT7wuloPVhzE7LN2eDz9e\nxSbP34kbN582by36y+Q/kxbqWbzzcdZX0jPGB8UwLXoif551Ja/9+gFby3bwzdG1/Fa+kxpLLacl\nnsJFI86V7t160VyIOljKqBURIAo+9JbC5lq80+YOQxesYcM3WdK5sAgxzCz0DRGQe4Hb7cbqtPHg\nlsdxup08dcq/COiHX/6NtpZv8F/nfodCJqfEVEaAIoBTEmYxsw/yS3cm0CcgA3xw6PM211icVrSq\n9n+hWRxWjjaXf5wZO5VEfXy3P1utUKFWhLR5Py10OMWNpVSaq0jS933P8UB1FvJ2EuvmGQukgOxN\nnpKgiyNBH4dcJkenCeLikRewq3Iv3+Wvl35ud9V+KSC73C5y6vKQIePslEVkGMYRr4uluLGUn4o2\nc2rCnD5/vpOF1eKZL45JCCFhWBgqtZK924uIigs+4YZJhcFDBORj5HQ5WXHwY9JCUpgVNw2Ar458\n69cTLGgoYmRYWgd36D0HarL8jr888g0AU6InDMj2ldY5rNsrTGBxWP1ev3foE6ZHT8KgjeS5zJYy\nf95tOsfLEOhJz1fZVN3nAbnWUsdLu98EIFpr4I7JN/Lw1qcw2ZuosbSkULQ4rcQFxfD36Xf4/Xyg\nMoBobRQFzfuvAWJ8FluVmsqxOC0k6OI42yc9aLwulitGLemrxzqhVVc0UlNlYsQY/3Sv1uYFXGqN\nZ3oldZSB1FFi4ZvQt8SirmP0XfaP/Fq6nfcOfUKj3dRmzhbgw6wvabSb2r9BF+qtRh7b9hw/F//a\nrWvBs5DJNxiODk/v0WcfL5W8656DxSf71pr89eys2MNre9/h4a1P0WBvBDxbdXqLFJDN1b12z47U\n+qQNDdGEEKzWc9+MuwBPtaoPDn3Gv359ArPDLC2Ca21EmP+z+6YpPVLnqSU7N35Gbzd9yCkvMeJ0\nuo77Ph+/tZ0fVh1k/84Slj+/iZoqz/+3tuYesiZA9FmE/nNC/2tbnbsGq9PGnLjpRARGdLsKUZW5\nhs9zVnPJyAv8fiECfJ+zUXqdWb6bhubAq1UGsnT0xfx377uUN1Wwu3Ifc+KO/RfnZ9lfU9BQTEHW\n50yNziC7NpddlfsoNZVx5aiL/ba61Fo9va7wgFCePfUR3G43RlsDIZrgjm7fp3z/fC9L/x0fZn0h\nHY8OH8nBmsNk1x5heIhnA39VO0FSJVdx44Rre61NLQG5qtfu2RHftKH1zcE5SKVFIVOQbyyS/r6A\nDvdFxwX5542us9bzUdYXZBjGsbNyHwDjIkb3dtOHBGOdmR2b8wmN0PLrhlwAZi9MJWP68a/Z2LjG\ns7r9oze2ceYFY7FYPHP87WWQEoS+ckL/a/u2ufrP+sKfOTN5Ieendl3HtdZSxwNbHgU8vZNzUk4n\np+4ojbZGZsZOpdzU8ovdaGtgY9EW5DI598/8P/RqHTdlLOPl3W/SYGs85vbuqzrIjoqWQgB3bXzA\n7/yOit0k6ONwupw8uu05SkxlqBVqogI92Z1kMtmABWPAbzXwlKiJZNfmMjZiFE0OM2Mj0nlqx8us\nyv2OfdWHOC3pFLJrc9vc46HZf+/V+ffwwHBkyKhs6vsesm9APnf4mYBnwVlKSBI5zb1brxhtVLv3\nCFEHSz/ncrukNKAbi7cgQ0ZKcBJhAaF90fw+VVttQqfXoFAqcLvdbcrldceqD3bTUO+fAGbz+iOM\nmRjnl6yju7zzxK399P1hLGY7mgD/koCC0Nd6HJBXrVrFG2+8gVKp5LbbbiM9PZ27774bp9OJwWDg\niSeeQK0euE3bdpf//2zby3dyVsoiVueuYVbsNGKC2v5CPFqfz5M7XpKO1XIVn2V/zdayHQCUNpXj\ncrsYETqc7LpcKeBPj5ksJdEIbv7v6tzvmRc/i6AOFjC1VthQzKt7lgOe+cfydvbsbi/fxcHqLKbG\nTJISZ9wx6U8dLpLqb959r0n6BLSqQK4fd6Xf+RmxU1hXsJHc+jxy9+YBEB4QxsyYKVKKz2NJRtKt\nNsmVhAeE9k8PuXnO/NaJN5Dus4YgXhcrBeRxEaPJrc/j1MT2F2CNCh/BFelLGB46jIe3PuV3zo2b\ndJ8914Odsc5Mk8nG1g/OjtIAACAASURBVB9zKSmsJzYxBLvNidVs59IbpqNSdS+Iut1uSgrq2gRj\nr+2b8pi1ILXdc+3d69CeMsIitWTvL29zfni6QarK5HS6OiyKIAh9oUdzyLW1tbz00kusXLmSV199\nlXXr1vH8889zxRVXsHLlSpKTk/n00097u63HpHXVoWpLLXdtvJ8fCn7ioa1P+i0uAs9iLd9gDLC2\n4EcpGANsKPSUWGu9mjUqsGWxhzeguHHz+t53u9VWu8vBrsp9uHFz3ZjLuWvKzdK5S0f+jhcXPEaw\nWk+NpZbCxhIp1eHCxHn9usUq52CFVOasPd45ZIer/Z5H6+F/gJTgJFJC+jYHbbQ2CqOtwW8FeHe5\n3W6/MpBut5sd5bt4adebbbYgef/NRQSE+/0i9wbns4adxo0TruWRufe1+2cBnlGOOfEzOsycNVQy\nalVXNPL+q1v5YsVOqeZvaWE9VeWNNBitfPvpXtxud6f3sJjtbFxzmLef28SqD3a3OX/pHzyLKg/s\nKsHtdlNf28Qva7N59bEf2bOtqM31breb4vw6fvw2iy9W7GRfpn/ymmtumUVwaMvoTPp4UXZS6F89\nCshbtmxh1qxZ6HQ6oqKieOihh9i6dSunnXYaAAsWLGDLli292tCu1FsbeHjrUyzf/wHrCzby/iHP\nF4Lzhy8munl40DdQeCseee1qnp8DT33g1nwzGcUERUs1YwF06pYeqnfIESC7ru2QbGsHqrO448d7\n+K65t50ePgKtSist+knQxyGTydrMLQKMDOter6A32KwO1n51gE+X7+jwGu8csnePbWtz49rmnE0K\nTmBU+Ajmxc/izxOu653GthId5Ali7Y06dGVN/nr++vM/pZXPHx7+grf2r+RATRbrCjb6Xdvk8ARo\n338PABMix3LfjLs4J+UMZDJZt9YyyGXydoN2R4F8sHA6Xaz9aj/rVh/0e1/fqj5tcX4dh9vpofra\nvC6H/TtL2h1a1gVrCI8MInF4ODark32Zxez8tZC9O4pxu2HTuhy/67dsOMIbT/3MgV0lbe4FEBap\nRavTkDrKgFwuI2N6InMW9v1OCUHw1aMh66KiIiwWCzfeeCNGo5Fbb70Vs9ksDVFHRERQWdn1L7+w\nMC1K5bHP/bRna9ZvlJrKKTWVS1mPAGYMn8DisfO46et7/a63yiwYDHrp+K317wNwxYQLOT/9dK6a\negEr935FdtVRbpt1PRHaMJ7b8iYOl4MxScMYlzycD7I8+2yjwsL87jUjYRJbizxtCAyRo1O3n9ln\nV+kBaZsMQHhgKMPjPYH/P2f8lUOVR5ieMhaZTIZeq4Xm0qvJoQnUmuuYOCyd8EB9e7fuFt82d6Wq\nvKVnHBEehLydOUC91hOIXLg6vPfVE5ewu+wAu8s8v7BHxQ0jOiqEW6OuPpam++nqOdLqk9hQCC/s\nep03Lnyi06Iarf1vw1pcbhePbXueuUnTOGLMl859l7+e7/LXMzNxMheMOgOnzBM4EqIjkcv9/3yi\n6Hpuv/VzjIgcxrZi/55hYpQBQ2jP/877WsHRGnIO+v+/nzIikoBAFQf3lBKk17D4grF89l4m+zNL\nmDpzWIfztC5n2x50XFIoZ5w3hrCIIPQhAUyalkhhbg1Ou5uDu/0rezU12Ege7lnUV3CkBofDxZFD\nnraFhAWSnBqBWq1g++Z8xk2Mx2DQYzDoGfVobI/muAejY/l/fDA7WZ6jx3PIdXV1vPjii5SUlHD1\n1Vf7DT91NRTlVVvbe6X6lPa289XLxi0l1BWJ2wRLR1/Cewc/ls457W6puILv0OOwgBSqqz0rp89L\nPBsSAQvUWyxcm35lu0UZ7E1uv/eWjrgUnUzPusKNrNzxNb9LO6fdNr+/80u/4xEhqdJ9VGgZrx9P\nVZVncdio4HR2lOzl6tGXMi1mkucZGqGysfMCER3pTnEJX7/+3NLbP7CvFG2QmsK8GkaOjZa+VEUq\nPT3RRF1Ch/eeET6DGeEzOBCdxa7KfcTKO762t54jyOX5n8DisLI1Zy+jmudhSxrLeGXP21wz5jIp\naUe1uRaH20G01kCj3YTL3bK15peCbe3e/9fCTCqM1diddgIUGunfz/E+R4wmBvAPyLZGqLT3/M+r\nr1WWtd17PmlWEjIZFByt5owLx2CI05M2OoqcgxW88dzPXHTVpHYLNjQ0eKaVLrhyIkql/P+zd96B\nbVb3+v+82pIlWR7y3nacYcdZZJIdSNgQRoCwKaXQli5+hdsWbm/vbW8p3PZSKJdCW2iBAoFQKKOB\nEEiAkL3jLDtOvPeWbG29vz9ky1YsJ7bjJI5zPn9Z73t03nMk+X3ec873PF82fV7CpOkp6E0anG4P\nzgYPWkNAzGsqW/u8/2/PbeK626egUilob+tZrtBolVxz6ySMZh1ejw9LrIHscXHBz3+w/xsjFdGP\nkUV3P04mykMS5JiYGKZMmYJKpSItLY2IiAiUSiVOpxOdTkddXR1xceGjSM8U0+InM9k6Ebung9cP\nr2Z20gwmW/OD5ydE5zIxdgJT4wr428E3OdB4mDaXjUitKWg/CQH/5MFy4p5ShaRgctxEPqv4kk5P\n+HVLt89Nma0n6YFJY+S6nCv6vcasxIuYHj/lpD7QZ4qqshZ2by4Pvv7HKz2ZlZrrO5h7aUDg5iXP\nQq/S9cnIFI4JMWOZEHN29kvH9wrgs/eKfn/l4Js0O1v4313P8/NZPyZWH8Ovtv0Wl8/NzbnXkdO1\nH3pc1BhkZI609EyDPjT5m/hlf3CGo90VuGEMZ4R4fK9I7CnWiexu2I9RPbJ9lDvsoYlOHnh0QXA9\n/c7vzAkeX3L1eBQKiaIDdZQfawlrutFhcxFh0pCUGvifvO62KX3KdEdXt7YE/s+yx1lJSInk63WB\n7+q913pmyzJzY8mfmoQ1wRR021KplX1MQQSCc8WQ5mXmzp3Lli1b8Pv9tLS00NnZyZw5c/jkk08A\nWLt2LfPmzRvWhg4EpUJJpNbMg5PuDRFjCKTje6DgbmYkTGV5zpV0eDvZVb+Xo63HeXp3wCHq1rHX\nDypvbvd6Xoy+b9q1GF3gmMvn6nMO4C+FgSlyozqCpxf8ip/P+jFmzcmnM86FGAPs3hp4cIgIk+ps\n/84q9m4LnFcqlMxMnDbicg+bNSZmJEwFwN5rNqTC3rOe+Jvtz9DkaAlmzlpV9F5QgFNMSXxvyv0s\nS18MwMqxNzAuegwTYsby7KInSDUl0+hsptHZjE4ZulZ6OuTHjGNGwlS+P+Vb3DfxDp5b/OQ5+w0M\nlKrywEj1utuncO8PLu43SlmhkMjMDWzXs7c78Xp7MmN1drhpqrdja3MSYTr556lWB25hrU2B79Wa\naKLgohSuuHFin7JzFmeTkhEtrC8FI5YhjZDj4+NZtmwZK1YE7A0fe+wxJk6cyKOPPsqqVatISkri\nuuuuG9aGDifppkBkst1t528H3wQC21HmJM0YVD0PFtyD2+8OG2ij7boxO30uGh1NfFq2getyrkCv\n0rO/8SCFTYE11Gnxk1Ar1agZuTeJpjo7JrOWW++fyYv/EwhkWn7HFN59NTD62LO1AqNZi1qjIi1r\nZCY4mJ04nW21u/jo+FoUkoL82HEh550+F5X20ICf7sQQ3SJ7VdZSLklbEPLAoZAU5MeMp8JWBRBi\n3HK6qJVq7ppwy7DVdzYoPhgI1DKZtacUPlNkYDahrKSJTZ+XMGtRFlNmpvHq/20Orh+bI08+46A6\nYeuUwRB4aEzPiWHG/Ewaam0cL2pk0oxUzJaR9aAoEJzIkNeQb7nlFm65JfRm8fLLL592g84G3TfU\ndredZmcgUuob+bcPOlXhyW6+WqUGCQmn18XbRf+ksOkwPtnP7eNv4pPSnuQB1+dc1W8dZ5pOu4tj\nRxrJGmfF7/Oza0s5EyYlERvfsxfY75fp7HCTmBKJUqVgydXj0epUJCRH8uC/LeT9N/ZQVdbK2vcO\nAqFTlCOJ7qneTq+DVUXvIknX9ynT20O6N0opcNNXSIqwo//LM5awp2E/KkkZ4jF9oXGksDb496lG\nthBIY6hUSlSVBUbVW9YfIy0zOiSYa+aCk9uonijI+oieWZxpc87sdjqBYLgZ1U5d/WHoWvPdVLMN\ngIviJw8q8nYgSJKEVqkNpBtUB57yd9Tt5uaxy3F4AwYH12VfEeJudbbZvrGUg3tq+OrT4uCxA7uq\nue9H84Jrc+4uk/3uSNjcvND1Ns0JwTgdNhdG88hL4B5xwtprUdd0tISETEAAdtYFAqhyLdkUtZYE\nyzY6m09at1Kh5LGZDw9nc88rvF4fnXY3n38YcBVLy4oe0EOZUqXAmmiitrInEOytl3b0nFdKpxzV\nKhQSM+Znsu3LgPGK8J4WnM+Mjtj+QXLizTla13cNeHiuY8Du6QiOsDx+L8/u/hP1jkayItO5NH3h\nGbnuQPB6fX22iXRTW9WTJMHpCOwp1urD3+jypyWTnh0dHBHZbeHXzE+HgUbtnwzjCW5mu+r3AfDr\nuY8TZwisZTY5m4nUmFk+JjQqPj8mdHpb0IO93cnrL2zl73/cGjymGYQoZo6J7fecL8y2p3BMm5PO\nnMXZWGIMRMeO7KA3geBkXJCCrFGqQ0R4MILs8/n5am3RKU0NACxaM62uthDTkZK24132m2fP1ONE\nvF4ff/j153TrXHySGZVaQWJqYC38w1X7OLwvINaOzoAg97dXNCUjiituKmDSjEBqww6bO2y5oVJf\n084ff/MFzz+xAb9/6Nl9lAol0+P7RumaNEauzurxOE81JQXX/yHgrV1gzRvydUczsizz6v9tCfnO\nxxckMusU08y9mTC5/2WfidMGng970oxUbv3mjCF5WgsEI4ULUpABIntFNE+MHXj2nPVrDlO4q5rP\nPjiE1+M7admTuSplRqYN+JqniyzLeNw9bke1le20t/b4Al9/51S++fD8kMjU9f8K5Fq2tQa2k5hO\nEVxj6Fq7czqGT5DdLi/v/K1ni5Wj00NlaXNIRO5guDvv1pA81d3rynplT9+SjUlolT3rkGdq9mQ0\nEG6G5eoVk075W+mNRqtizuJs9AY1l93QszPirofmMHvxuXtoFQjOBRfsgktTVzDXzIRpA7YjlGWZ\nnZt7nJpKjzaRM75nr2i3mX5CcqC+3pmX0kwpuHyuoH3j2bRA3Lejkk2flbDi3ouIjNJTV92zZnfx\nJT0CdWKquU/ePYA+IjAytkSffC2vO6LW6QjvYz0UHJ2h4l58oI7N64+RmhXNVSsKqDjejM/tR6kZ\n+HPl0vSFRKj0LMtYQpQu8B30DtSK0kWiUZy7pCjnE3u6tsPlT02itdmBz+dHp1djs4dPAtEfk2ak\nUjA9BY878KA1YXJi8AFPILiQuGAFuTuYaiCp7GRZpqHWhlKpwOX0otYo8bh9wb2Px440ULirKhgt\nese3Z2E060KSEvxo6oP889iaoCAPd1aj/ig5XM+mzwIBSr0DZiBgpm8whkbDTp+XwfavSgGCWW/0\nBjWJKSf/nHRda8z9pbQbLJWlzShPsFUt6WpPxbFmmhs6+HBVYB04MlrPjXdNG1Du2vHRuYyPzg05\n1jtBh0pSYVDrWZq+iIyzmLjjfMPr9dHW4iAxNZJ5S3ORZfm0ouslSUKjVY3YKH2B4GwwqgXZ7fIi\ny+EjLx8ouJu1Zeu5NG1ByHGv14fs73EA6rC5+PjdQuqrbUFjjPxpyezeXM72jaWkZEbx+UeHg0/3\nADs3l7NgWS5zk2dT2HSYb+Tfjlqp5srMpayv2IhKocKkDi/Isizj98soFBItTZ1ExRhOeoPyuH34\n/f6QPZ8+n58OmwuFQgpuRwrHiWIMgQCZyTNT2bL+GPt3BvbWLrgsF6Xq5KPQ7s/Y5QyfWGIwHC9q\n5ON/FPY53lDTY5+36i89NpZtzQ4aam1ExUYgSaA3DH101W28cW325UOu40KgvjrwXcRYA9P+wyWi\nQowFFzKjWpA/eHMv9TU27v3BxX1MCpKNidyTt7LPez597yClRwPJ7C+/MZ81q3uEodsWMCU9Kmgl\n2W2O0ZuDu6vJGWclNT2JX13ck9RCr9LxP/N/gc3d0a/j0vuv76G6oo1xBQkc3leL3qBmweVjyciJ\nCXuzeu+13TTW2/nWIwtQKCR2bioLbgHpzaTpKWSNtfLlJ0WkZEZTMC0l7PUlSUKlUjKuICEoyGnZ\nMWHL9qb783UNw5R1az8e5ycLtra1u4Ip+h78t4VDvrZ+GK0vRzPdQX+ZuedHOkiB4HxgVAd11XeN\nqF57fiudHScPNmqotfGn334ZFGMgRIx7R3yaLTqWXtcTeavWKLnx7mnc/b05weMNtT2eyb3Rq/TB\nbTbh6M4de3hfwGTB0enh43cKqS7va54P0FgfuM7rf9xCyeH6sGJ8/Z1TmbMkh4SUSFZ8YzpzFmeT\nmdN/GwAsMQYSUszkTUkaUOab7uliW7uTogN11FS0Dmq70qG9Nez8uhSfzx+cKu9m9qLQqN24RBPj\nJyUyq9fx1ubTS1TyyEUPsSRtPnlii9OAaGnqRKGUSE4fvPe7QCAIz6gdIfeOKna7vHy1tohly/P7\nLV92tAmvJ7CtZuK05ODoEALro3MvHcPYiQnYW12YLfqQSNLp8zKwJgSito1deV877cO7H/f9N/Zy\n9S2TSMnoifrtLUK2dlfY6enbHpg5JMtAlUrJ8tunDri8QiGh1alorLPz2QcBW9Cl100ge1wg6K1b\nnPubktywJhDVva1r/RrAYNSw8LKxRMUa2Lw+kG1q5oJMps5OD9aZPcbK31/cyvGixuD7fD4/nXY3\nh/bVMGl6yoC8i9PNqSFryYL+aai10dzYgcmsE1PMAsEwMqoEua66HUdnIMr5xJGivd1Fe6sjaGBw\n10NzQiI5u03xV9x7EdHWCC6+JIfig/U4Ot3BvZLWBBMTJibR0GALuRFpewUTda8zD8Ugo6Yi0AaT\nWYutPfD+sfnxHCkM7HkuPlgXIsjdo+jIaD1tzT1ZpcbkxVF8oB7grPr3arSqkKCuuqpANLdao6Rw\nZzXNjR3c9sDMAd/Er79javDBZ9GV4ziyv5assT1TpJIkkZVrJSrWQEtjz8PJuvcPBUfZarWSKbPO\n3hazC4GNnxbj9fjF5yoQDDOjRpDrqttD0gJ2022rV19jC3ET2vx5CUuuDuw/9nn91FS0Em2NINoa\nERSME20i+6N3LtduL92Sww0UH6wbcGo3r8fHR2/vByBrnJW92wK+ymPy4jl6uAGf1x+M6gbYvaWc\n3VvK0RnUXHfbFDasOUJGTgydHW7GTUwgKiaC+CRz2GudKU4M/Nq7vRJOSCHsdnlDRqxOhwdHmOWE\n5XdMCZmFGDcxgXETE/qUkyQJa4IpRJB7T3k3Nw4+N7Ggf2RZprHeTrQ1gvGTEs91cwSCUcWoEeTe\ndo/d5ObFM3lmKseONNBYF7qm6/UGpqd9Pj+7Npchy4G1yaFMwal6CVHv9dbPPzo8IEF2Ob18uGov\nHrePcRMTmL0oOyjIhggN33x4Hqv/upPaqnY+/kdhyPTs0msnYIjQ9Ek3dy6M9VWniMSGQF+7Bdnv\nl3n5918HzyWlRpKQGkluXjxRMQO3QAxnl7j8jimsWV1IUWEd0bERYjQ3TLhdXrwe/ymzMAkEgsEz\naoK6csbFcfGSHPKmdE8vG1ly9XiUSgXX3DqpT/ljRxooKqzl7Zd3sOPrgNlH+gCiicNxonNUalcK\nQkmSTmr32NLUycf/KOSlpzcGA9CmzE5DkiSWXD2elIwoLNGBbU+eLlew3mJstuhIShs5QTW9Bbm/\n0VN3sgqAI/trQ87Fp0Qyc37WoMQYAtP63UydncbMBZkkJEcGTVu2bDg27Gv6FyrdSxKD8asWCAQD\nY9QIcoRJS8H0FC6am0H2OCuXXDMheE6rUzNnSV8bvs8+PByc6rzx7mkh65MD4ZpbJ5GZG0t6TqiQ\nX35DPmPz4/F5/VQcb+n3/V+vKw4R2CtXTMQSHUiCkJsXz9W3TApOA89fOgaVWkFKRhSpWdFYovUs\nv33KiAqq6U6Fp1IrmDo7Lbie3pu3X95J2dEmDu6tpqUpdDq5e0/rYDEYtUyZnUZcoomL5mYEg75y\newn1qaLsBQOj+4FKOwATFoFAMDhG3X+VIUITsiWpm4KLUogwasnIieFPv/0q5NxFc3uipAdDcnoU\nyel9vY6VSgW5XcFYZSVNYUfe3e5fEIhGTsuKOakxfkpGNN98eP6g23g26X54iIzSY7boufO7c/hw\n1V4qjrdw0cXpwZmIf60OrJUnpATWuK9cMZG6qnayxw19T+usBVkQ6vFCXGLPd9phdxM7sOV8wQls\n2VCCx+1j3tJc3K7ATM1AXNEEAsHguGD+qyRJCk5hzls6hq/W9uQANplPnUx9sER1rWv2Z5Sx9cvj\nOB1edHpVcGvQ+U73lLXP2zNNv/S6PDrsLqJiIujscHNwT09CgtrKdswWHWlZMaRlDW254GRIksSi\nK8ay/l9H6LSLEfJAkWWZthYHlmgDJYcb2L0l4FltitQFA+1E3mGBYPi5IP+r8qcmBwVZpVaQPX74\nBbG3lWRlaTOff3SEq1YUEG2N4HhxY9DpaziTMZxrugXZ20uQNVpVcDQ1Y35miCBD6Cj2TGDomjYX\nU9YDo/hgHevePxT23Ob1x8iZEPhfscQYwpYRCARDZ9SsIQ8WpTKw9lpwUQpq9fDnUFWplKjUCpwO\nD9u+LKXD5gqaX3z5SVGw3EgKyjpdum/S3evgJ6I3aLj9wVnBRBTAkJYKBoMhIjD7YW8fXAaiC5HG\nOlu/YtzN0YP1aLRKEpLP7pY6geBC4IIV5KtvmURCspmC6eE9nYcDvUFDh90dHKXVVbdTcbw5ZPp0\n2fK+693nKwXTU5i1MIslV/VvP2mK1HH9ndOCr8/0SCsqxoBGq6SytP/gOkGA3u50vVnxjYu47Pqe\n32nOhPgBuZ8JBILBcUFOWQMkplpYfsfArSGHgtmio6qsNSSSujtl4OxFWeRNST5pINf5hko1MFes\nyCg985eN4fC+WpLT+gbFDSdKlQJrgomqslY8bt+o+rwHisvpoaiwjrETE2hvdaLRKsM6uLU1O5Ck\nniQecYkmrr1tMiqVksionvKZY4Z/vV8gEFzAgnw2MJn7N09IzYy+IMWhm7wpyeRNST51wWEgOjaC\nqrJW9u+sDG6JupAo3FXNti+Ps3Hd0eCxcBmx2lodGLt+s7Y2J1fdXICqKye1SqVkweW5lBY1hd1Z\nIBAITh8hyGcQfYTmhNdqHB2BfMGGMHt0BWeGqNjAtPjWL46TPc5KZNTZCUjy+2Ukqf+EGg21NpQq\nRb9r7qeLLMt43D4qjjX3OdfS1IHT4aWtuZO07BgUColOu5vkdAvLlufh6PT0mZaeMCmJCZOSzkhb\nBQKBEOQzisfd4+B1w11T2bz+GI6OVqwJJnR6sQZ3tujt/NXa7DijgizLMrVV7WxeX0Kn3Y3L6WHJ\n1eNJzw7NZy3LMqv/ujP4Om9yEvMvyx22dtTXtHNgd3UwAYnZosPj9uHoDDwQvvmn7WHfF59kRqtT\nizVigeAcIAT5DDImL47CXVVcdn0ecYlmLrs+jw67m6gYw4hy2BrtdI+QIdS6c7hxu7z85X839jm+\nZnUh1942maTUnoj63lmxAA7sqWb24qyQRCVDpbaqjXdf3R18HWHUsOLe6ciyTNGBupA9+Ccydbbw\n/BYIzhVCkM8gCcmRfOuRBSgUAfEVI49zg96gYeJFyezfUdVHCIcTW1vo1qply/PYvaWc+hobTXX2\noCD7fP6gS1tv/vy7jX3Sgg6Go4fq2f5VaNpRa4KJS64ZH4xXyJ+aTEZODC6nF0enG0mSeP+NvUDA\nxGU4HggEAsHQEP99Z5huMRacW9Kyos+4IPt8PYYoCqVExpgYjGYt7/xtF20tPfmq17xTGFzXvfiS\nHL7uFWxVU9E2ZAvRLetLgnm0TZE6Vn5rZtjfn9Gsw9i1jbj3Q8TpWJcKBILTRwiy4IKg2y3szE5Z\n98QMmCN1KBSK4Hp1U0MHbS2ddNjcIUFWiSmRRMUagklOykuahiSMbS2dQTGOMGm4/Ib8AT0MGs1a\nJs1IITElctDXFAgEw4sQZMEFQff2Ha+n/3SYp0vvIL5u+1CtToXJrKW6vJXXX9gWUl6hkIiKMTBz\nfiYtDZ1s/eo4LU2dJ72G2+WlcFcVLY2dqDWBfd+mSB1lRwMiv+DyXMYXJA44RkGSJOYszhlMNwUC\nwRlCCLLggkCt6fbZ9p2i5NDxuHtG3+MLevJBZ4yJ7eOCFRtnZOnyCajUSjJzrcy42MThwlpamzuR\nZblfQd27rSKYNQvgwO5qNFolEcaARWhiikUEDAoE5ykXrHWm4MKiZ4R8eoLscfuorWzDE6YeZ9f6\n9Ix5GUyd02NAYgyTTcxk0fXZfpWYGonL6aWmoo2Wpk5KDteHjLoBWpsDI+jemut2+YIja7OlfzMa\ngUAwshEjZMEFgaorgYhnkFPWToeHxjo7KRkBd6rPPjzE8aJGJAluvm8GUb28uJ1de3wTUy0h67e5\n+QnYbS7GTIjnH6/sAsKL9JgJ8RzeV8uuzWVUHA94b4+flMjCy8cGy9jaXEgS3P/jBUgSFB2o44s1\nR/D5An6XSqV4xhYIzlfEf6/ggkClDvzUy4428UWvbFunYuO6Yj54cy9FB+qoqejxJZdlqC5vDSnr\n6AwkDdEbQre2GSI0zL1kDPFJZtKyowGIS+ybLSkpzYLJrA2KMUD5sWYKd1Xh8fjwen001tmItkag\nUEhIksTY/ASuXFEw4P4IBIKRixghCy4Ieo8cD+6uZsGyXDrtLr78pJiZCzND3Lx6U10WEN3PPuib\nlrCtpROX08vX64rJHhcXdMHSGfrfa77sujxqq9pJTu+bdlOhkEjPiaFwV3XwWIfNxVdri6k43kz+\n1GR8PrlPQo6kNAszF2SSICKlBYLzGiHIgguGBZfn8sWaIlSqgDhv31jK8eJG7DYXN949Lex7lKr+\nJ5H2bqtk77ZK+QzWXwAAIABJREFUAIoP1hOXZEKSOKktqkqtDE5/hyOyH1/r0uKm4F7mrBO2RUmS\ndEEmzRAIRhtiylpwwTBhUhJJaRa8Xj9+v5/mxg4gkJ4wHH6/jL1rb283ufnxzFmczYmBzH6/THND\nBzq9+rSinI2mvmvL3bQ0dpI9zir2DAsEo5TTGiE7nU6uuuoqvv3tbzN79mweeeQRfD4fVquVp556\nCo1GZDQSjCzUXcFdrz2/hQ5bYM23vdVJY52N2HhTSNlOuwu/XyY23khjnZ3c/HiWXDUegLTsGFQq\nBV98fCS45ut2+Yi2nl6Uc8aYWKbNSSc1K5r3Xtvd57xw0xIIRi+nNUJ+/vnniYwMPK0/88wzrFy5\nktdff5309HRWr149LA0UCIaTDntgxNstxt28G0b8nI7ANqaE5Ehuf3AWi68cFzwXFWPAFKnjqpsn\ncc/3Lw4ej403nlb7FAqJGfMziUs0hT1vtuhPq36BQDByGbIgl5SUcPToURYuXAjA1q1bWbJkCQCL\nFi1i8+bNw9JAgWA4ycyNDXu828HL4/bR3hpYq3V3GX1odEpMkbp+p6J1ejXL75hCwfQUps4anmxJ\nSqUCU2Tf0fZQE08IBIKRz5CnrH/zm9/w+OOP89577wHgcDiCU9QxMTE0NDScso6oKEPQsOF8wmoN\nP3o537gQ+3HZtflMn53B/z25AYCrV0zig7cC2Y6ioyJ47jfraW3u5KI56WSPjQMgKirilNewWk1M\nnJwytA70qqM3+VOS2byhBICFl42l5EgDaRkxIz5hyWj4XY2GPoDox0jjVP0YkiC/9957TJ48mdTU\n1LDnZVkeUD0tLSf37R2JWK0mGhr6ps4737ig+9E1L6SPUJOSFcX4SYkc2lvDkUO1QSesHZvK2LEp\nYFFpa3ec8c8qXD9SMqNgA2SNtTJ+ciLjJyfS1GQ/o+04XUbD72o09AFEP0Ya3f04mSgPSZA3bNhA\nRUUFGzZsoLa2Fo1Gg8FgwOl0otPpqKurIy4ubsgNFwjONPd8/+LgSDPGGtiDXFXWGrastZ/13DNN\nbLyRm++bTqRYNxYILgiGJMhPP/108O9nn32W5ORkdu/ezSeffMK1117L2rVrmTdv3rA1UiAYbnrv\nFdZ2/b15fUmfcleuKCA1s/99w2ea6NjwhiUCgWD0MWz7kB966CHee+89Vq5cSWtrK9ddd91wVS0Q\nnFE02tA4hknTe9aCUzKiRPYkgUBwVjhtp66HHnoo+PfLL798utUJBGed7r3J3SSlW9i7PeDANdID\nqAQCwehBOHUJLnhOjEFMTgv4TJ/LqWqBQHDhIbysBRc8vXMIG81a1BoV9/94fh97TIFAIDiTiBGy\n4ILHbNGj0QaeTSOjAhHNSqUChUL8ewgEgrOHuOMIBEDOhMA2vaS0vmkRBQKB4GwgpqwFAmDGvAxS\n0i1k5IS31hQIBIIzjRBkgQDQGzRkjxNmNgKB4NwhpqwFAoFAIBgBCEEWCAQCgWAEIARZIBAIBIIR\ngBBkgUAgEJwW7ppqOouOnOtmnPcIQRYIBAJBH2RZxl1f3/Pa70f2eoN/dx4+hOz14q6tofTxn1L5\n5K/x2trPVXNHBSLKWiAQCARB7Pv20rj6LdzVVQAkPvgdTNOmU/nUEziOlZDxi1/SvOZftH/9FWpr\nHJ6GHtGufvb3xN64AkPu2HPV/PMaMUIWCASCCxxZlmle8xGN/3yX6mf+NyjGAG0b1gPgKC4Cn4/S\nx35C+9dfAQTFWKHXozAYcB4rofK3T+JpbDj7nTgJstdLw1tv4ig5eq6bclLECFkgEAgucGzbttL4\nztvB1+Y5F6PQG2j97FM6Dx2k+V8fnvT9CffehzYtg8Z3V2PbshnHsRLUsdaQMu7aGtTxCf2mM5Vl\nGUdxEbrMTBRqzWn3yVVVSeeRw7Rv+hp3VSWyx0PL2o/J+b8XUWgC9Tev+Qi/y0XMVdcgez0odAHr\nXMexY7R8/BHRV1yNLiPjtNsyUIQgCwQCwQWM3+Oh8d3Vwddxt9+JZeFiIDAC7ti3l8Z/BM5HLlhI\n/B13A1D+3/+J89gxIiZPwThlWuD8xfOwbdmM81gJxinTUKjVAHQePkTl//yGqMuuwHrjij5t6Ni/\nj6rf/w4Aw4Q8Ym9cgTY1bci5yD3NzZT9/LGw56qfewZdZhb2PbtxV1YA0Pzh+yBJIMuY581H9niw\n79qJffcu0n/+n2hTUofUjsEiBFkgEAguUNq3bqF941d4GxuRtDosCxdhWbg4ENDl9aPQ6ULKR86d\nH/w7/o57cNfVYpw6LXhMm5oGQOu6T+k8dIiMX/wSv8tF5f/8BoCWj/+FLjMT2/btRF26FKXRiCY+\ngcZ33wnW0XnwAOX/+XPi7/kGkRfPA8DvdCBptABIA0j60vLxR8G/lWYzUZcsxTxvPqU/+wmdBwrp\nPFAYOGex4GttDRTsysPa/tWXPRXJMnWv/JW0nz5+ymsOB0KQBQKB4AKh7csv8Dk60eeMwXHkcHDk\nK6lUZP7q16gsUazZWsbb60sAuKujlcSu96rj49FmZAbr0qamok0NjBx9fj8ASqMRbVo6rvIy3FWV\nNL3/Hk3vvxfShprnnwPAvmMbAHF33I2rvAxDXj7xd91D9bO/x1VRTutn6zBMyKejo4mj3384+P7M\nJ3+LOjombP/8HjdtX35B6+efAZD6039Hn5UVPB9/+500vPMWxslTibpkKWqrNRg5LqlU1Lzwf9i2\nbwuW1+eOxVFyFNnvH9CDwOkiBFkgEAhGMbLfj6/DTvvXG2lc/Vaf89rUNKKvXc7nRTaKKivZVdQT\nkNVicwUFOe0njwenkI+Ut7D1UD03Lsim0+nhyTd2o5AkfvnNmcRcfQ3Vzz0L0EeMw1H/6l8BME6e\nijo6hvSf/ydVzz1Dx+5dHP/xD/uUb/nkYySVkqhLL0NlCc3OZt+1i4Y3/h7oV3oGuszMkPOmGTMx\nzZgZckxS9chg3B13g0qFt7kZ46QpGPLycVdVnhUxBiHIAoFAMCrpLK+g+qVXcVWW42noEVml0YQm\nMRFNUhK6jEz0s+byu7f2UlTRE4H8g5smsfdoI5Xr45hgL8WyeAk7KzpoaG3EatHzx38eAECjUrB2\ne0XwfTsO1zNz8lRir78xOPoGiL1xBVGXLKXxH6tp37KJzF8/BQqJow/eHyggSZimzwiWT3rgO9T+\n+YWQ0WrcbXdS//dXaP3sUwDat2wmcu58IhcsRFKqqPztk0hda9YAifc/OOg1aKXBQOI37sfl9nG8\npp2chEhMycmDquN0EIIsEAgEo4yO/fso6gqS6k3cbXdgWbQk+Lq53cnqL0ooqgiso8ZHG3j45knE\nRuopyI7hP6paWaU28e3LlvPHF7f1qa+3GAO8+MFB/vl1KY/duYzcK66i6Jv3gCwTtfQyJIWC2Jtu\nxrrilmB5y5JLaf3sU2JvXIHSaAwel5RKYq67Hm9rK/qoSPxmC+a587Bt34qjyxHM19ZG80cfYNu2\nhch5C0K2aqX/x3+hiY8PaZtfllGcINAfby3H4/Vx2cx02uwuTAYNWo2Sd74sYd2OShJjDDy6cirm\niNOP+h4Ikix3rWSfAxoabOfq0kPGajWdl+0+EdGPkYXox8jhfO+D7PdTfP+9wdeKBUupVkdj1Kt5\nrULLrLwE1EoFtk43G/ZUA2DUq3niW7Mx6ELHaK+uPcL6XVUhx/RaFQnReirq7Xh9Afm4/5oJSEis\n21lBSVU79189gVl5CXjb2vA7HfijYvnnxuMsmZpCtFmHzeHBbFDjdzhwV1Wyy2Hkg01lRBo1ZCdH\nYtSrmT8pCaNejdVqYuPOcsrr7OQmRmApO4A6JjYYKAagio7G29wMgC47h+SHH+GLwnoaW524PD60\nGiWfbq9g8dQUrpiVxrqdlRypaOVoZVufz0+lVOD1+YOvZ+fF882r807zW+n5XVmtpn7LiBGyQCAQ\nnCe0rP0E287tmGfNxnn8OEqzmch5C0JGg57GxuDfz2XcgK0qolcNbj7eWh5Sp0qp4IFr8/qIMYDP\nFzpeWzIthdsuzQXg6bf3sq+kieTYCGZNSAAgxqzjv1/byatri9BpVCgUEp9ur6G0togOp5dPtvWM\nqMelWZiUE8viqTm8/fwm2jvc1Lc6KO4SyX0lTfzgpgLe+6KEv7wfiIrWqBT8eOUUYiP1JHzzW9T+\n6QWAoBinPPIT9rnNvPjKbqobO/r059MdFXy6o6cNEtDdwxizlqZ2V1CM8zOjaba52HGkgfuukoe8\nBWswCEEWCASC8wC/x03DW28A4OzlOOVrbyPh3m8GX3tbAuK0KWoiNlUEY1IiKa5sQ6WUmJgVQ3q8\nCbvDgzVKT4fDw1VzMlApwwct9R4pAlw6vWc/7oPX5tPY7iQhWh88lhIXEH+Hy8sz7+w7aX8Ol7dy\nuLyVLQfraO9ws3R6KrPzEmjvdPOPL45RVNHKt3/3Zch73F4/v3plJwDfWZ7PlOdeoP7vr2Lfu4dj\n+Ys4WKfm/a8PBctPGRPL/mPNpMZFMC49is93VeFy+7h8VhpXzspAr1UGy0qShMPlZf+xJiIjNGQl\nmSmrtVNa235WxBiEIAsEAsGIx+/xUP7LXwDg1ejwzFqMr7YGY9FuHKWldB46SGfRETSJibQcPQ5A\nh1LHM9+fh1Gvxun24vfLGHTqk12mD+PTo9hUWAvAcz+cj17bIxlajZLk2IiQ8jqNiu8sz+e5dwv7\n1BUXpSch2oDFqGVqrpUv91azq6iBslobRr2aZTPSiDIF9hqPS7PwzDv7OXC8Ga1GybyCRK65OJOH\nn/sajzfwkPDcu4VkJpqYN+VyHOMv4e0vjsHXpcHr3bQwm8tnpeP2+FAoJFRKBTfMz6ap3YnVou/T\nPghMx88Y3zPbkJMSSU5K5KA+s9NBrCEPkvN9fakb0Y+RhejHyGGk9OHA4WqOHy7DF20ls+4wuk9W\nU6+J4rWUZbgVgSCj+8r+Sayn7zooQNPSm5m94vLTaoMsyxyrbicz0YxCMfBRYovNRX1LJy9+cJAW\nm4s//GBe2IeB37+9l70lTdxzxTjmFSSFnOt0ethV1MhVC3JobQlMPze1OdlxpJ4v9lRT29wZ9tqz\nJsRz75Xj+x31nyvEGrJAIBCcZ/j9Mht2lpPyws/JBTySErXsA6A8LpeLCtKIjNDQ0OqgsCWLhU27\ng+/dGTmWKHc7Jp8Dy6RJp90WSZLITh78CDHKpCXKpOWX983E7fX3OzK/98rxlFS1Mymnr9GHQadm\nbkEialWPsMZE6lg2I41lM9L43Vt7KDzWHDy3fF4mV1+c2aee8wkhyAKB4LzAcayEhlVvoMvMpHXd\npyR99/sYJuQFEwWMJLqjd7OSzX222vSHx+tj0/5qSt9czeymvcHj3WIMMPe2q0kbkxJ8/WmqhZc/\nSuKeio84ZEynbtYVKGMjqHV6eXBaFg67c5h6NDT0WhV6bf/nTQYNk8fEDqnu7y6fSHmdHUmC9ATT\niBsRDwUhyAKB4Lyg/A9/QGpvCQY0Vf/h90gqFWk/+3nQwvFMU1lvxy/LFBbVEGXUkZpkISXeDMCa\nrWVsPViH0+WjoaWDNEctNTorsXEWJmREsfKS3LB1yrJMdWMHr7/4IUZbI0t6iXHsDTcFszBl/PIJ\nNAkJIe+99KJU5k5M5PNNE5k+IZFr43tGs0a9+pwL8plEo1ae1fXds4EQZIFAMGJpLCqhvrgU55av\nMba3AIFtKt1jTtnrpfwvfybn339+RuwNPV4/apUCn9+PJEm8+Mc1pNmrmNlyAK3soVmh5r8ybsSj\nUGPx2MjuqGR3ZC5X1W8iz3acOk0UNY0xFJel8YvKNhpbHXQ4veSmRDI7P4GZE+L537f20lF8lDur\nPg5e1zAhj7g77kJjjUMVFYUqOqaPGHej16q4ctG4Ye+74OwjBFkgEIxItq3+GMvHb6ICuj2carQx\n/C31SgC0aiVXlq8jt7KMIx+sZdy1l520PtnnQ1IqkWUZfD48jY0odFoUegMKbd951U93VPDGuuLg\n62m5sdxQ+Sl6vzt4TOf38J3S1fwr7mKWNO0g0mNnccselD4PAPHuFuLdLUxuP8oThuRgir+S8maK\nKtv428dHuLr2S/LspYE+paaiSUwm4d77gh7L5llzhvgJCs43hCALBIJhQ5ZlDpW14HR50WlVRJu0\n+GUZr0/GYtTg9clo1Yo+QT5HylsCI8dUC0fKW/h8VxVjtm3DckL90TOm89Jdi4OvN7zjgzWvUH3o\nGNX6XXRs3EC7w8u0O25kXEFPlp9dz7+MbtdGysfOJv3wJpT07K+Vx0wg6+H/17UdJpBucF9JE+s/\n3Mw36zZywJRFRmcNnzkvCopx3G13YJiQT+nPHkXn93B97YZgfUqfB21qKpHzF1L/91eDx7+vOYCh\ntR65phJZoeSQIZWtlrygGEddugzrzbeezscvOM8RgiwQCIaNLYU1PPVGIOpX63PjUqgDo8ITsESo\nMLo7SMlNY15+PLv/8GfUspdXogoweh1E+BwkO+oAyHn+RRxFRSD7MeRNDKln0rQxNKwBKo+TcrTH\na9n5h1/zcMFdPLJyKut3VZK+bzdG2UfW4Y192uI+WsRrP/lfojw2tkTlEzUmi6OlTfyg6hPUso/5\nzXsAuLF1CwDmhYuCftBZv3uG+r+/gn3njmB9sdffSOS8BSiMRpAkHEVHsG3biv7QrqArlOT3McFe\nypjOysDnsfgSIcYCIcgCgWB4OHC8mT//cz+LGncwseM4Bo+D7ZHj2Z0+E7vdiVtSk6xxk6J0kFG6\nj8y2Uj5tmM77Ww0sbzsMwKT2oyF1ahISUag1ROTlh72mMdpMA5DibAg5rvN7+NaeP7OmbCJzWvb3\neZ/h7gdZXaEkZ8s/ye2o4OKuMhPspWy0F6BVRQSjmw15+XQeKMRkbwJAn5YRrEdlNpP04HeRvV6c\n5eVokxJR6HpMJywLF2OaPhOUSiQkfI5OOvbsxpCXj/NYCWqHI1BuUc+oX3DhIgRZIBAMmU6nh70l\nTVQ3dvDR5jLy20uY2XoweH562yGm7+uyMszIQVlVj6+9PXj+0sbtJ60//t77TnpeZQh1irIsv5GO\nTV/hqQuMroNibI0n/TvfRZuSit/lQqHV8gOgqGYjHAx4G2uSkvC2tjG3pcfyMf0//gttSiqtn6+j\n8f33kCQJ45SpfdohqVTos7L6HAdQRkSQ+I1AmkHZ78e2ZTPGqdNo++oLGla/RdwtK9EkJoV9r+DC\nQgiyQCAYNGW1Nn7z+i6cbl/I8cURzf28Ayg9SndpSavFsmARLWsDkcX6MblYb1lJw1tvEn3FVTiK\njmCeOw+NNe6k7ZBUKqKvuobmD98HwJyXT9yVV+F3Ojn63QcAUOj1ZP/3E0E/4t4BXOkrbqD+dQfx\nd92LJj6e+jf/Tuu6T4Pnu4XSsvgSzHPnI3u9KA2GU39A/bVXocA85+JAnZcsJXLhYhTqwdlZCkYv\nQpAFAsGgqGqw8+Qbu3G6fSgkiWvnZVLf3ElyZy2GtYdQRceQ+MC38ba2Ypo6Db/bjX33Tmr/9ALR\nV15NzHXXI3u9SEolqpgYjAWTUVutAKT++N8A+p2iDkfsdddjmnYRHQcPoE1PB0Ch0zHmxZfoPHQQ\nVWRkv8kBtCmppD7yk+DrmKuuRSP7aN67j7hbbkNS9iQfUGg0MIwmJJIkIQkxFvRCCLJAIBgUL/3r\nEA6Xl7zMaG67NJeEaAOOYyVU/PcrABinTkWflR0sr9BoMM2YhT4nF3VMwCKxW4iillw6LG3Spqah\nTU0LOSYpFIMSdgCl0ciY731nRHhZCy48hizITz75JDt37sTr9fKtb32LiRMn8sgjj+Dz+bBarTz1\n1FNoRqClnWDwHK9p52BpM0UVbVw8MYGJWTE43T7cXh9tdjdJsREoJAmlUkKrVp66QsF5S6vdxfEa\nG/mZ0fzo5skAOEtLqf6/ZwGImT2LyCuu7vM+SZKCYiwQCMIzJEHesmULxcXFrFq1ipaWFpYvX87s\n2bNZuXIll19+Ob/73e9YvXo1K1euHO72nnNcHh9HK9uQJMhKMtPp8rJxXw17jwaSgus0Km69ZEy/\n6b2GgtfnR6mQBp2Ts73Djc3h4VBpM9WNHYxLj8Lnl4mN1FHa0MH67eUUHm/GoFPRanOhVCrITbVw\n5ax0osxaTHo1x2sCa4XdKc/2H2sKey1JChjK/9c3ZoakaDtdNhXWoFEpmZprRaGQcLq9KBUK1CoF\nxZWtOP3g7HRhMZ7EMFcwbJTXBUaOOcmRyF4vLWs/pvHdd6AraVzmN+6hHfFdCARDYUh3zunTp1NQ\nUACA2WzG4XCwdetWfvGLQL7ORYsW8dJLL52Xguz3y9gcHirqbGQnR9Le6WbrgTo6nIF8opsO1OJw\neQHIy4zmwPG+QSx7jjaSYo3g1ktyGZ8e1fcasozb42N3cSMHjzfjkwMiWdXQgUGrotnmYlyaBb8M\nu4sbKK+zA3DL4hwWT0tBpVRwsLQZt9dPfXMnXr+MSqnAYtTg98tUN3Xy4abSPtfdsKc6bJ9bbC6U\nCgmLUcmOw/XsOFzfp8yyGQGv4PW7qvD5ZSZmxVDf6qC6MZAWTZahud1F4fFmpo87eSDOqeh0elmz\ntYyiilaKK3tSyy2emsz6XVXIgEKS8PfKHPrUg3P4al81GrWSK2al4/fLNNucxJh1Zy25+EjEL8vs\nLW7kjc+KUUgSXr+fuy4bx8SsvqNVWZZptbtpbneSmRjwZ65vdfDyvw6h06jITY2kqS3gjZyudlL8\nQCACWhERgdIQgS4nB601FsR0r0AwJE47H/KqVavYsWMHGzduZPPmzQCUl5fzyCOP8Oabb570vV6v\nD5XqzE1x7jhUh8PpZc6kJJSnyOVpd3hY9ekR3vui5JT1WoxaWu2u4Ou8rBi+e9Mkokw6PttRzp/e\n60nO/cNbp5CWYOZvHx1kXHo0V83N5NU1h/hkS9nQOzYIrFF6xqdHo9UoidCrabW5cHl8mCM0eH1+\nJmbHkhATQW6aBaVCwb82HWfVuiJaba5gXx+8oYDZExORJIlOpwelUhGcmpZlGbfXT0WtjR8+/QVL\npqdyz1V5GPVqlIPMvuL3y3z/dxsorWk/ZdkInYoOpzf4OiPRHHxfQU4s+7pmLL5702SWzUofVDuG\nC5/Pj88vo+lnGv9wWTNb9tdwvKadB68vQK1SEBN58pmVNruLfcWNjM2Iwt/1IAZg63Tz6ppDVNTZ\nsBi1qFQKHC4vJZXhc+VOGxeH3y9T29TJvCnJjE2PYsehOtaEeZA7kUijhv/n3kTHwYOojEby/vPn\nGLPDb/kRCAQD57QEed26dbzwwgu89NJLLF26NCjIZWVlPProo6cU5OEMnDhe087z7xUSG6nD6fbR\n6fJS3xLYdJ8aZ2TuxESUSonCY82kxBm5bl5mMC2aLMs88fddIaMxgOTYCKoaO4iL0rNsRhpqpQKd\nXs20nBgcLi8PP7cJl8fHf903k+TYiGBdb60/yu7ixuD1e9N7ZJceb+KK2em0d7hRKCTGpVlotrno\ncHjYcqCOA6XNPHTDRPIyolm3o5I3PivGHKFBrZRoancxZUws6Qkm9BoVX+6rZlxaFG6Pj7zMaI7X\ntJOXEU1+mJEQnDoJe6fTw8b9tcwYHzeg6WC/LPPQ01/icAU2tkSZtDyycgqbC2sxaFVU1NvpcHr5\n7g0Tg5+7X5b5y4eH8Hh9ONw+DpW2hIx6C7JjmJUXT2aCmd+8votWu5vLZ6Vxxax09BoVMjLljQ7+\n+uEBKurt/bbt4okJ3HPF+AGnwTsdZFlm++F6XltbhMvjQ6tWMq8gkYVTkik81oQ5QsuYlEj2HG3k\n1U+O4PP39FcCblyYzWUz05AkifZON0a9OqTdL//rEF/tqxlUm8amWlg2M42C7Bj2Fjfy7D/6GmX0\nRqdRhmxnmpARxawJCew71oTP52fFRBNtT/4ClEqyf/t7lEZjsOypflfnA6OhDyD6MdLo7ofVauq3\nzJAF+auvvuL3v/89f/7zn7FYLCxZsoSPPvoInU7Htm3beO2113jmmWdOWsdwfsi7ixt49p2+N5rY\nSB2NbX1TkM2flMRdl41lzdZyPt5ajt3hQQJ+cvs0spPN/U5z9v5xNLY5aLW5+00B9sTfd1FU0Rq2\nHT+4qYCC7P7zgPr9Mi6PL7geK8syDpe330Tfg2UoP3J3XS1KowllRETY8794eTtldSev06BVMTsv\ngaxkMyVVbXy+q6pPmR/dPImxqVEhicn9fpmGNgdxFn3Id2O1mth3uJbX1hbR3ukmISqwR/TeK8dT\nXNnG028HUtndedlYFk5OHlR/w9HU5uRoVRsxZh05KZG4PD5Ka9pJthrpcHr45d92hIzcT0VGgoma\n5k5USgUdjkBCApNBjd8v0+H0cvfl41BIEjqNkgOlzXzRtewQZdLi8frJTgr8Vo9UtHLRWCs3LMym\ntKadsWlRKBVS2ByxHq+PnUcaOFTWwpgUC298VoTD5eOSaSksnpZCbKQOW6eHCJ0q7Oi+9q8v0b7x\nSxK//RCmqdNCzo2Gm+do6AOIfow0zpgg22w2Vq5cyV//+ldiuiInH3/8cS666CKuvfZafvnLXzJ2\n7Fhuuummk9Yz3B+yLMu4PX6OVLSSEK1Hp1VhNmjYcbieVZ8X09TuCvs+vVbF2FQLd1429pSjwXA/\nDp/djm3ndlzl5fhs7VhvvR11VBQut49NhTVMyoklyqSlvM7Ol3ursZi0XDU7/ZyubQ7mR+5tb6f1\n809p/vADlCYTmuQU9GNyicjLRxkZiTo6Bkmp5JnV+9jTNVUcZdLSYuv5vLuS3ITl+vlZ1DR1Mn1c\nXJ9k5T67ndYNn6PPzsEwfkLIOb/bjTXOTFNr/zlfDxxv5rerAl7EybERPHrbVIz6gT/UlFS3sWl/\nLePTo9hUWBvs34nERxuwd7qDYnz1nAyunZtJY5uD594tpKLezthUCx6fn2PV7VgtOm5ZMoYpYwL7\nb61WE9uoWPFhAAAgAElEQVT3V/H6uuJgcnvou1aeGGPgW9fkkRYf+k/t98soTrEs0x+yLA/4tyj7\nfJT84Lso9AYyn3iqT8rD0XDzHA19ANGPkcYZE+RVq1bx7LPPkpmZGTz2xBNP8Nhjj+FyuUhKSuLX\nv/416lNsej8XH7K/KxvNb9/cEzz2vRsK+ghBf0SbNRx98x9IOh3mWXPwNDZQ++cXcFf3BExJGg2p\nj/wEXUbmSWo6t1itJqqLyrFv34o2LR1Jrcbb0oJCr8cwIS94g5b9fkof/ymeutp+69IkJaHLzKZe\nZebpqhium5vJNXMzabW7MEdoUEgSsixTWmvjd6v2hIwgf3TzJPIzw0+r+91ujj3yI/z2wHR0zPIb\naP7wffQ5uUQtXUb1839AdrvR544l6Tvfo/alP6E0mki45xvBOmRZ5sNNpbz71XEA5uQnMH9SErmp\nFjxeH/uPNZOfGR12JOjx+vnpi5v7PMiduH7dm+TYCH586xTMEaFb/nqLnsvjQ61ShExFd/+zutw+\n3v3qGOPSonjmnX0hdWjVSv77/llEmc5dFLO7tobSx36Cec7FJNz7zT7nR8PNczT0AUQ/RhpndMp6\nODjTH7KjuBhXdRWyz4suPYOO/Xtp37IZ86w5rDPms3ZHJd9Zns+0sXH4nQ5aPl1LR+F+vM1NeNva\niCiYhNoah+z1ICmVmKbPpOWdVdiLivtcyzh1GsYpU3HX1QVt/KwrbiVq6bIz2sehoqmvoPCnj/d7\nPu7Ou4mctwB3dRVlP38MQ14+lkVLaHh7FbLbRcSkKbirq/C2tQZ9gwH0D/87SWMzUJ4iWXyH00Or\nzUWy1djnnOz10vr5Z9h2bsdZcjTMu/uitsbhaQhEh+vH5CLLMpr4BGKX34DKYmFfSVNw+hoCW9aO\nVfcEj/309mnkpERSVNHKv7aUUdfcSV1XDECKNYIJGdGMTbMwJsWCUa+mvcMNUmAKXqGQ2He0CYfL\ny5jUSGJPEZgVjnA3nc2Ftfz148NMzbVy57KxOFxeos26Qdd9usiyDLKMpFBg27mDmuf/QOyNK4i+\n7Io+ZUfDzXM09AFEP0YaF6wge9vaaF7zEa3r1vZbJuHBh+jIGEecHhxHi6n985/wdwa28CiMxuCo\nbCBYFl+C9ZaVSAoFsixT9vhPcdcGAm+Svvt9jJOn9HmPLMs4jxbjqqkmYuIk1FF9t0cNB7LXi6ex\nkdYNnyEplXibmzHkT6Tu5b/0KauKjcXvcODv6OhzLv7Oe4icvwDZ6wWFIjhVKXu9dBw8gG3bFmxb\nNhN3x91YFiw8rTbb9+2h+pmng6/148bjOHwo2EbZ40Gh0WCcehFSaxPNW7f1VxX6Mbkk/+jHoFLx\nsz9tpa65s9+yNy3K5u31faPsf3bnNLKTwscJDBf93XQ8Xh8qpeKcLW90HjlM5VNPoIiIIP7Oe6j9\n0x+RvV6SvvcDjAWT+5QfDTfP0dAHEP0YaVxQgix7vdh2bkdljqTyt08Gj2vT0vE01COp1Phs7SFi\nqzBEIHvcyJ5AMI0mMYnk7/8QdawVv9tN5+FDNL3/XmCt1GSi88hhlC4Hsffej6RSU/Xs07gqysl6\n8nchkabe1lY6Duyn7uW/hJ3ac1VWUPfaKziP9oy09bljQaEg5sqr0WXn0PblBiLyC1BGRKAwGgd1\nQ7bt2knDG68habT9TzUrFETOW4Bl8RK0ySnBw36Pm7YN62lY9UbwmGF8HokPfLvfYC7ouXFrkpKQ\nNFq0KSnE3nATtu3bUOr1+Gx2lJFmzDNnh32/s/Q47toaOvbtw7ZtS/C4JjmF1H/7Ge6qSvwOR2A6\nvZe/sNVqovidD2j6xzvIXg+WJZciKZVYllxK7Ut/omPvHlAqyXn2eTwoabW72F3ciNPtJTPRTHy0\ngZ++uCVck8jPiuYHN006K9HZZ/KmI/v9OIqL0GfnIKn6tx6QfT46Dx7A09iA2mrFefw4Te+/13fx\nP0x0dTej4eY5GvoAoh8jjQtKkFu/2ED9q38NvtYkJWFdcQuGvIkhYib7fNS//hptX6wPHtNmZGKe\nNRvT9BmoIi0nvU7vH4ff6UD2+cMKlez1Uvzt+9FlZhFz7XLqX3uFmKuvwThtOpW/fXLAU7EASpOJ\nqMuuIHLu/OC1ZFnGVVZKx769GPLyUVvj8NlsNH3wT+w7ekaMquhovM3NqKKiibl2OfbdO1FGRGCd\nUoByysx+r+l3Oin/7//EOG06sdcuP2UbPU1NHH/04VOWS/l/j9J58AARkyajy8yiY/8+VBYLFU/8\nKvhgBIHvL/XfHjtlZp3u70P2epG9npBctH63m6PfDqS9048bT+r/ezRsHfUtnfzbCwFRXjo9lVuW\njMHh8qJWKcJGKZ8JztRNR5ZlGle/Rcsna4LH4lbejmnGLPwuJ7LXiyY+AYDav/6F9o1fhbxfGRlJ\n5MXz0OXk0PrZOtTWOKw33RySMels9ONsMhr6AKIfI40LSpA9TU2U/cdj6LKy0aamEX3ZFWGf4Ls5\n9uMf4m1pQR0fT/p//HLAKdAG8+Mo+8W/46ooD3tOl51D8kM/QBERQceeXXgaGml4642QMpJGgyYh\nEVd5j4lIxMQClOZIHEVHgmum4Yi67AosixajjonFZ7ej0OlCRkfD/SOXZTng3OTznbrwKUi4/wHM\nM2YNqOyp+uE4WkzFE78CQJOSStrP/j3sd/3ZzkoKjzXxwLX5aDVn34/7TNx0/G43tX95EfvOHSct\np8vOQVKrcRw+hCYxCV1WNkgS2qQkTLPnoDKZB3zN0XDzHA19ANGPkcZABHnUZHtSx8SQ8+zzAy6f\n/L0f0rzmI+LuuPuM5SM15OX3K8gJ99wXfGAwTgns5TSMn4CzvBTDuAmoY2KQ/QH/6NZ1a2nfshlX\neRkd+3sib3VdGXWUZjPumhqUBgOSVkvstdejHzMmWO5kDybDhSRJ6NIzcB4rQdJoyPz1U3Ts3YNh\nwgQUWh1+t5v6N16jY8/uPu/VZmTirq4i/ef/hSY+fljbpcvOwTRzFratW3BXVtCxdw+mi6b3Kbdk\nWgpLpqWEqWHw+F0u2rdswl1VhTouHsuSS8IuOdh376LjQCGuinIM33sQIoaefEGWZVrXraX1s3Uo\nLRY8jQ34OzqQPR60aemB35vZTMunn+BtbsLX6cBVUYavrS04WyNpdSTcex+6TOG6JRCcC0bNCPls\nMZinNXddHfVvvIYmIRHzrNnIXi/tm75Gl5lJ5LwFg7qu7PPhLCtDUkjIfj8KrQ5t8tCNLs7EU2dn\n0REqn/w1iQ98J6zoQWA9U1L8//buPSqq89zj+HcGBhjuiBBuAioqCkE0Fi2YWBMTTRMFTeJSTlxa\n09g21qxqTlPjaZdWY4wrjblUTTTxktqIeHJMTa09FYLaYw1eqYRodUQIl4BcRIHhMjCzzx+UaYho\nwah7z/B8/gJmBt4fz555Zr/73Xv01B34C1cP5xC28HncQkKxtbbiYrw9q5Ov+5uKQuWWzTTkdlxJ\nLmDK9wl6cmav/1ZPVf/Pf1P35z/Zv/caNZp75szD1bdjT/Pakb9Sf/RvNF843+VxnSvbe7JeQGlv\np+3KFZoK8mmtqMBSVkqz6UKX+7j4+eObnELgY493mcr/OqvZzKUXX0CxtBK9cjVuoWG9jduFM+zN\nOEMGkBxa06emrO8WZ9s4bjelvf2mC4dut57msLW2cnHRT+Cfsw5D3tvWsUI87zReIxNveEy0N2wW\nC2WvvUpL0SUA7vnBM9RlHcBSVgp0TJmjKFjKy274O/o9Po3+aTNu+ncURaH8rXU0FVx/ZbqgWem0\n1dbiN/7+Lov1bjru1lZ0rq5dFsvdKmd4fjhDBpAcWtOnpqyFNtzNZtwbend3Ihb/J+Xr30ZpbeFq\n9gEa807TfOE8/R6fSv+0J7p9XNOF81w7fIjAqamYC/IxFxRgrb9Ga8mXeI9JwjM2Fo+oaNxCw2i+\nVGhvxl6jRuOXcj++303BtGA+gL0xQ8fK9ZAfLsDVz4+2mmra/36C0l27qfvf/RhjYria8ynmLwoI\nf34xXnHx9se1FBdRueU9LBUdF6LxjIvHc0QctXs/xvu+MQRMeuSW/jdCCPXJHnIvOdu7NUfX2xzX\n/u8wlz/Ydt3PB/ziv7ocd4eOPdGSlctvuA7g6zyHx6E3etB4+lTHldqW/hcekR2fMtVceJHqXTvx\nf2gS7XUdp8TdM2del+PlQUE+FGX9la/eWd9lYZyLvz+u/gH2NwQNx3KxNTXhETOE0GcWYAjquPSm\ntbERnbv7HVsP0VPOsF05QwaQHFojU9Z3gLNtHI7uVnI0F16kdM3L1/18yLvvY21spK26GuOQIZgL\nPqf8zdevu59nXDx6d/eOletu7lw7lGO/zcXbh0FvvN3rC3l05mg4dZKKze/gFhJ6w6nt/k/MpN+j\n118lSwucYbtyhgwgObRGpqyF6IZxcAyhP16I3tMTpa2Nr37bcVWwsnWvdSyM+sZ71OA58/CIjMRw\nzz1gtXXsibr961rVQTNnUfvHvTR9UYDfAz1blHUjPveNwfP1t9B7eXFl3yfU7v24y+0RP1+K57DY\nW/79QgjtkoYs+qSvrwIP/9kSyt9cd92qZwC/iQ/hm5xy06lgvZsbQU88BU/c/NPNeqrzNLXAqano\njZ7ojR7odHqaC00Yhwy9LX9DCKE90pBFn+cxuOuxY78HJnDtr4fxHvMd7vmPOSqNqkPApIftX/sm\np6g4EiHEnSYNWfR5LkYj/R6fxpV9nxA0K52ASY8Q/PTcjg9xFkKIu0QashBA4OPT8Eu5375qWfdv\nPj5SCCFuN3nVEYKO86c7m7EQQqhBGrIQQgihAdKQhRBCCA2QhiyEEEJogDRkIYQQQgOkIQshhBAa\nIA1ZCCGE0ABpyEIIIYQGSEMWQgghNEAashBCCKEB0pCFEEIIDdApyjc+/FUIIYQQd53sIQshhBAa\nIA1ZCCGE0ABpyEIIIYQGSEMWQgghNEAashBCCKEB0pCFEEIIDZCGLIQQQmiANORvaGxsVHsIt4Xk\n0BbJoS3Nzc1qD+G2aGpqUnsI35rU4l9cVqxYseLbD8Xxtbe3s2nTJjZt2kR7eztGo5GAgAAURUGn\n06k9vB5rb29nw4YNbN68GU9PT0JCQnBzc1N7WL0m9dAWZ6rH+vXr2b17N/7+/gwYMEDtId2StrY2\n3nnnHXbu3ImrqyuBgYEYjUa1h9UrUovryR7yP23YsIGamhpeeOEFysrKyMrKwmazOdSLDUBmZiYm\nk4mlS5cSEBCAh4eH2kO6JVIPbXGWerz//vsUFxeTnp6O2WzGZrOpPaRb8pvf/Aaz2czMmTPJycnh\ns88+U3tIvSa1uF6fbsidG0BDQwNnzpxhwYIFjBw5kpCQEGpra9Hr9TjClUWrq6vtX5vNZlJTU4mL\niyMoKIjy8nIVR9Y7Ug9tcZZ61NXVAWC1WqmpqeG5555j3LhxDB8+nJqaGpVH13tXrlzh6NGjLFmy\nhAkTJhASEsL58+cBNF8PqcXN9ckp69bWVpYvX45Op2PAgAEYjUZCQ0MZNmwYANeuXaOoqIgHHnhA\n03sAdXV1vPrqq2RkZFBWVkZERATFxcWcOnUKs9nMW2+9RV5eHsXFxQwcOBBPT0+1h9wtqYe2OEs9\namtree2118jMzKS5uZmBAwdy6tQpjh8/TmVlJe+++y6HDh1CURTCw8Nxd3dXe8jdampqYvny5QwY\nMMA+HRoZGcnAgQOBju2uoaGBpKQkzdZDatEzfXIPuaamhtzcXM6ePUtpaSkASUlJ9ts//fRThgwZ\notbweuyDDz7AaDSybds2fH19+eUvf0l6ejo5OTlcuHCBjIwMfvzjH9PS0kJWVpbaw70hqYe2OEs9\nNm7ciLe3NytXruTKlSv8+te/5ic/+Ql5eXlcvnyZHTt2MGvWLM6fP09eXp7aw72hoqIisrOzycrK\nsi8cGj9+vP32rKwsBg8erNbwekRq0TN9siF/+eWXTJ48ma+++orPP/+clpYWoOPgfEtLCyUlJUya\nNAmAEydOaG6asXMq0cfHh5iYGAwGA/PmzaOxsZEjR47w05/+lCNHjgAQHx+Pv7+/fSGRFqe0pB7a\n4uj1UBQFi8WCl5cXEydOZMCAASxcuJCSkhIOHDhAWloax48fB+Dhhx/GbDZjtVpVHvX1FEXBZrNR\nWlrKD37wA44fP05+fr79dqvVyrVr16ioqGDy5MkAfP7559TW1qo15OtILXpXC6efsu5uFWhAQAAT\nJ05EURRyc3OJiIggKCgIFxcXdDod58+fx83NjQ0bNnDu3Dm++93v4uPjo1KCDo2NjfYX8c48x44d\nQ1EUhg4disFgYNCgQaxatYq1a9dy4MABXFxcaG1t5aOPPmLo0KEMHz5c9Smtr+fo5Ij1+DpHrkd3\nHLEely9fxtvbG5vNhl6vx8XFhT/+8Y+4ubkRFxcHQHR0NOvWrWPNmjXs27cPPz8/9Ho9+/fvJy4u\njkGDBqmaAa7PodPp8PPzY8KECTQ3N3Pw4EHGjh2Lu7s7er2e1tZWampqMBqNvPrqqxQWFjJu3DjN\nHA7R6XQOW4uv0+l0d6UWTtmQO/c6Vq5cic1mIzo6ussLn4uLC3q9noEDB3LkyBEaGxuJiYnBzc2N\noqIiVq1aRWVlJVOmTGHhwoWqvtjU19ezfv16CgoKSExMxMXFxf4mw9PTk8zMTEaOHElAQADh4eEc\nO3aMpqYm5s+fT1lZGTt27GDatGmkpaWpluFGOTo5Uj3q6urYtGkTVqsVf39/3N3d7auNHake3eXo\n5Ej1aGhoYOPGjaxcuZJHH30UHx8frFYrer0ePz8/3n77bdLS0jAYDISHh5OXl4eXlxePPvooZ8+e\nZfPmzUyfPp3vf//7qmW4UY5ORqMRnU5HXFwcH330Ea6ursTGxgJw7tw5XnrpJWpqapgyZQo/+tGP\nVGvG9fX1vPfee7S1teHj44PRaMRiseDi4uJQteguR+c2dadr4bQNWa/X8/rrr9Pa2srQoUPx9fW1\n/1M7V4d2/oNPnjxJYGAghw8fJjk5mdDQUBYvXszw4cNVzZGRkcGaNWsYMWIEzzzzjH3PsrMBBAcH\nYzKZKCwsJDw8HD8/PywWCzabjbFjxxIbG8vUqVPtG4xWczhKPcrLy1m6dCkeHh72d8xhYWH2N4CO\nUo8b5XC0emRmZrJu3TrCwsJISEggPj4eT09P+xvW8PBwTp06hclk4jvf+Q56vZ6ioiL69+/PmDFj\nSExMZPr06ZrPodPp7HvMRqORv/zlL9x3333k5OQwbtw4wsLCWLJkiao5srOzWb16NYGBgZSWlpKV\nlWU/rAE4TC1ulKPz+XCna+F0x5A7/1n19fX069cPs9lMfn4+zc3N9r2ykydP2uf/k5KSqKqq4sUX\nXyQ3N5fGxkamTZuGwWBQMwYVFRXk5+eTlJTEggULcHNzo76+HsA+dXju3DnGjBlDS0sLW7Zs4eOP\nP2bnzp3079/f/nvUnhK9WQ69vmPzc4R6AFRVVQGwfPlynn76acaMGQNgf6I6Qj3g5jnAMepRUFBA\nTU0Nr732GosXLyY/P5/W1lb7FKlOp8NkMpGenk5hYSFbtmxh//79HDp0qMu54J2Z1XKzHJ1jO336\ntP04/aRJk6isrGT27Nnk5uZisViYOXOm6vWorKwkNTWVn//850yfPt1+kY/O2RZHqAXcPAfc+Vo4\nxR5ySUkJhw4dIjY21v4OBjpOz4iPj+f48eOMHDkSNzc31qxZw5/+9CceeeQRfH192bt3L2fOnOEX\nv/gFzz77rKoXbigpKeHgwYPExsbi4+ODTqejqqqKuro6tm/fzuHDhzl27BgPPPAAa9asITMzkzlz\n5pCUlITBYODYsWPMmTOH+++/X7UMt5Ljk08+YfLkyZqsR+d2BR2nA128eBEvLy/eeOMNcnJyOH36\nNOPHj9d8PXqTQ8v16NyugoODSUpKsk/tlpaWYjAYiI6OxmKxsHr1anbv3s28efNISEigoaGBnJwc\nfvjDHzJu3DjVMtxKjn379jFp0iTc3d3ZtWsXJSUlvPjii8ydO1e104O+uU1lZWVRX1+P2Wy2Xyij\nqamJESNG8Morr5CRkaHZWvQmx969e3n44YfvXC0UB2Wz2exfL1q0SHniiSeUo0eP2n9WVVWlzJ8/\nX1EURVm9erUyc+ZMZffu3UphYWGX31NeXn53BnwD3eX429/+piiKolRUVCi//e1vlSeffFLZs2eP\nUldXp8yePVvZtm2bYjab1Rpyt25XDi3Wo3O7unjxorJ8+XJlxYoVyp49e5QrV64os2bNUrZt26Y0\nNTWpNeRu3a4cWq6H1WpVbDab0t7erqxZs0Y5ceKEoiiK0tbWppw9e1aV8d7I7cphMpnu3qC/obsM\n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\nYII=\n", + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + } + } + ] + }, + { + "metadata": { + "id": "Z_B_Otn8yrVv", + "colab_type": "code", + "colab": {} + }, + "cell_type": "code", + "source": [ + "def get_johansen(y, p):\n", + " \"\"\"\n", + " Get the cointegration vectors at 95% level of significance\n", + " given by the trace statistic test.\n", + " \"\"\"\n", + "\n", + " N, l = y.shape\n", + " jres = coint_johansen(y, 0, p)\n", + " r = 0\n", + " trstat = jres.lr1 # trace statistic\n", + " tsignf = jres.cvt # critical values\n", + "\n", + " for i in range(l):\n", + " if trstat[i] > tsignf[i, 1]: # 0: 90% 1:95% 2: 99%\n", + " r = i + 1\n", + " jres.r = r\n", + " jres.evecr = jres.evec[:, :r]\n", + "\n", + " return jres\n", + " \n", + "coint_res = get_johansen(series_df,1)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "metadata": { + "id": "QjgRQE80ywyC", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + }, + "outputId": "86a02930-8c5c-4117-8954-fc4ad4201017" + }, + "cell_type": "code", + "source": [ + "coint_res.r" + ], + "execution_count": 0, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 38 + } + ] + }, + { + "metadata": { + "id": "5iz3TB0jzVy2", + "colab_type": "code", + "colab": {} + }, + "cell_type": "code", + "source": [ + "" + ], + "execution_count": 0, + "outputs": [] + } + ] +} \ No newline at end of file diff --git a/Graphs/Implementation of Depth First Search.ipynb b/Graphs/Implementation of Depth First Search.ipynb index c111e89d..6dcde0ef 100644 --- a/Graphs/Implementation of Depth First Search.ipynb +++ b/Graphs/Implementation of Depth First Search.ipynb @@ -156,21 +156,21 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 2", "language": "python", - "name": "python3" + "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 3 + "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.3" + "pygments_lexer": "ipython2", + "version": "2.7.15" } }, "nbformat": 4, diff --git a/Trees/.ipynb_checkpoints/Binary Search Trees-Copy1-checkpoint.ipynb b/Trees/.ipynb_checkpoints/Binary Search Trees-Copy1-checkpoint.ipynb new file mode 100644 index 00000000..04781356 --- /dev/null +++ b/Trees/.ipynb_checkpoints/Binary Search Trees-Copy1-checkpoint.ipynb @@ -0,0 +1,301 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Binary Search Trees" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is the code ot go along with the video explanation. Check out the video lecture for full details!" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "class TreeNode:\n", + " \n", + " def __init__(self,key,val,left=None,right=None,parent=None):\n", + " self.key = key\n", + " self.payload = val\n", + " self.leftChild = left\n", + " self.rightChild = right\n", + " self.parent = parent\n", + "\n", + " def hasLeftChild(self):\n", + " return self.leftChild\n", + "\n", + " def hasRightChild(self):\n", + " return self.rightChild\n", + "\n", + " def isLeftChild(self):\n", + " return self.parent and self.parent.leftChild == self\n", + "\n", + " def isRightChild(self):\n", + " return self.parent and self.parent.rightChild == self\n", + "\n", + " def isRoot(self):\n", + " return not self.parent\n", + "\n", + " def isLeaf(self):\n", + " return not (self.rightChild or self.leftChild)\n", + "\n", + " def hasAnyChildren(self):\n", + " return self.rightChild or self.leftChild\n", + "\n", + " def hasBothChildren(self):\n", + " return self.rightChild and self.leftChild\n", + "\n", + " def replaceNodeData(self,key,value,lc,rc):\n", + " self.key = key\n", + " self.payload = value\n", + " self.leftChild = lc\n", + " self.rightChild = rc\n", + " if self.hasLeftChild():\n", + " self.leftChild.parent = self\n", + " if self.hasRightChild():\n", + " self.rightChild.parent = self\n", + "\n", + "\n", + "class BinarySearchTree:\n", + "\n", + " def __init__(self):\n", + " self.root = None\n", + " self.size = 0\n", + "\n", + " def length(self):\n", + " return self.size\n", + "\n", + " def __len__(self):\n", + " return self.size\n", + "\n", + " def put(self,key,val):\n", + " if self.root:\n", + " self._put(key,val,self.root)\n", + " else:\n", + " self.root = TreeNode(key,val)\n", + " self.size = self.size + 1\n", + "\n", + " def _put(self,key,val,currentNode):\n", + " if key < currentNode.key:\n", + " if currentNode.hasLeftChild():\n", + " self._put(key,val,currentNode.leftChild)\n", + " else:\n", + " currentNode.leftChild = TreeNode(key,val,parent=currentNode)\n", + " else:\n", + " if currentNode.hasRightChild():\n", + " self._put(key,val,currentNode.rightChild)\n", + " else:\n", + " currentNode.rightChild = TreeNode(key,val,parent=currentNode)\n", + "\n", + " def __setitem__(self,k,v):\n", + " self.put(k,v)\n", + "\n", + " def get(self,key):\n", + " if self.root:\n", + " res = self._get(key,self.root)\n", + " if res:\n", + " \n", + " return res.payload\n", + " else:\n", + " return None\n", + " else:\n", + " return None\n", + "\n", + " def _get(self,key,currentNode):\n", + " \n", + " if not currentNode:\n", + " return None\n", + " elif currentNode.key == key:\n", + " return currentNode\n", + " elif key < currentNode.key:\n", + " return self._get(key,currentNode.leftChild)\n", + " else:\n", + " return self._get(key,currentNode.rightChild)\n", + "\n", + " def __getitem__(self,key):\n", + " return self.get(key)\n", + "\n", + " def __contains__(self,key):\n", + " if self._get(key,self.root):\n", + " return True\n", + " else:\n", + " return False\n", + "\n", + " def delete(self,key):\n", + " \n", + " if self.size > 1:\n", + " \n", + " nodeToRemove = self._get(key,self.root)\n", + " if nodeToRemove:\n", + " self.remove(nodeToRemove)\n", + " self.size = self.size-1\n", + " else:\n", + " raise KeyError('Error, key not in tree')\n", + " elif self.size == 1 and self.root.key == key:\n", + " self.root = None\n", + " self.size = self.size - 1\n", + " else:\n", + " raise KeyError('Error, key not in tree')\n", + "\n", + " def __delitem__(self,key):\n", + " \n", + " self.delete(key)\n", + "\n", + " def spliceOut(self):\n", + " if self.isLeaf():\n", + " if self.isLeftChild():\n", + " \n", + " self.parent.leftChild = None\n", + " else:\n", + " self.parent.rightChild = None\n", + " elif self.hasAnyChildren():\n", + " if self.hasLeftChild():\n", + " \n", + " if self.isLeftChild():\n", + " \n", + " self.parent.leftChild = self.leftChild\n", + " else:\n", + " \n", + " self.parent.rightChild = self.leftChild\n", + " self.leftChild.parent = self.parent\n", + " else:\n", + " \n", + " if self.isLeftChild():\n", + " \n", + " self.parent.leftChild = self.rightChild\n", + " else:\n", + " self.parent.rightChild = self.rightChild\n", + " self.rightChild.parent = self.parent\n", + "\n", + " def findSuccessor(self):\n", + " \n", + " succ = None\n", + " if self.hasRightChild():\n", + " succ = self.rightChild.findMin()\n", + " else:\n", + " if self.parent:\n", + " \n", + " if self.isLeftChild():\n", + " \n", + " succ = self.parent\n", + " else:\n", + " self.parent.rightChild = None\n", + " succ = self.parent.findSuccessor()\n", + " self.parent.rightChild = self\n", + " return succ\n", + "\n", + " def findMin(self):\n", + " \n", + " current = self\n", + " while current.hasLeftChild():\n", + " current = current.leftChild\n", + " return current\n", + "\n", + " def remove(self,currentNode):\n", + " \n", + " if currentNode.isLeaf(): #leaf\n", + " if currentNode == currentNode.parent.leftChild:\n", + " currentNode.parent.leftChild = None\n", + " else:\n", + " currentNode.parent.rightChild = None\n", + " elif currentNode.hasBothChildren(): #interior\n", + " \n", + " succ = currentNode.findSuccessor()\n", + " succ.spliceOut()\n", + " currentNode.key = succ.key\n", + " currentNode.payload = succ.payload\n", + "\n", + " else: # this node has one child\n", + " if currentNode.hasLeftChild():\n", + " if currentNode.isLeftChild():\n", + " currentNode.leftChild.parent = currentNode.parent\n", + " currentNode.parent.leftChild = currentNode.leftChild\n", + " elif currentNode.isRightChild():\n", + " currentNode.leftChild.parent = currentNode.parent\n", + " currentNode.parent.rightChild = currentNode.leftChild\n", + " else:\n", + " \n", + " currentNode.replaceNodeData(currentNode.leftChild.key,\n", + " currentNode.leftChild.payload,\n", + " currentNode.leftChild.leftChild,\n", + " currentNode.leftChild.rightChild)\n", + " else:\n", + " \n", + " if currentNode.isLeftChild():\n", + " currentNode.rightChild.parent = currentNode.parent\n", + " currentNode.parent.leftChild = currentNode.rightChild\n", + " elif currentNode.isRightChild():\n", + " currentNode.rightChild.parent = currentNode.parent\n", + " currentNode.parent.rightChild = currentNode.rightChild\n", + " else:\n", + " currentNode.replaceNodeData(currentNode.rightChild.key,\n", + " currentNode.rightChild.payload,\n", + " currentNode.rightChild.leftChild,\n", + " currentNode.rightChild.rightChild)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "yellow\n", + "at\n" + ] + } + ], + "source": [ + "mytree = BinarySearchTree()\n", + "mytree[3]=\"red\"\n", + "mytree[4]=\"blue\"\n", + "mytree[6]=\"yellow\"\n", + "mytree[2]=\"at\"\n", + "\n", + "print(mytree[6])\n", + "print(mytree[2])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "** Check the video for full explanation! **" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/Trees/Binary Search Trees-Copy1.ipynb b/Trees/Binary Search Trees-Copy1.ipynb new file mode 100644 index 00000000..04781356 --- /dev/null +++ b/Trees/Binary Search Trees-Copy1.ipynb @@ -0,0 +1,301 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Binary Search Trees" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is the code ot go along with the video explanation. Check out the video lecture for full details!" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "class TreeNode:\n", + " \n", + " def __init__(self,key,val,left=None,right=None,parent=None):\n", + " self.key = key\n", + " self.payload = val\n", + " self.leftChild = left\n", + " self.rightChild = right\n", + " self.parent = parent\n", + "\n", + " def hasLeftChild(self):\n", + " return self.leftChild\n", + "\n", + " def hasRightChild(self):\n", + " return self.rightChild\n", + "\n", + " def isLeftChild(self):\n", + " return self.parent and self.parent.leftChild == self\n", + "\n", + " def isRightChild(self):\n", + " return self.parent and self.parent.rightChild == self\n", + "\n", + " def isRoot(self):\n", + " return not self.parent\n", + "\n", + " def isLeaf(self):\n", + " return not (self.rightChild or self.leftChild)\n", + "\n", + " def hasAnyChildren(self):\n", + " return self.rightChild or self.leftChild\n", + "\n", + " def hasBothChildren(self):\n", + " return self.rightChild and self.leftChild\n", + "\n", + " def replaceNodeData(self,key,value,lc,rc):\n", + " self.key = key\n", + " self.payload = value\n", + " self.leftChild = lc\n", + " self.rightChild = rc\n", + " if self.hasLeftChild():\n", + " self.leftChild.parent = self\n", + " if self.hasRightChild():\n", + " self.rightChild.parent = self\n", + "\n", + "\n", + "class BinarySearchTree:\n", + "\n", + " def __init__(self):\n", + " self.root = None\n", + " self.size = 0\n", + "\n", + " def length(self):\n", + " return self.size\n", + "\n", + " def __len__(self):\n", + " return self.size\n", + "\n", + " def put(self,key,val):\n", + " if self.root:\n", + " self._put(key,val,self.root)\n", + " else:\n", + " self.root = TreeNode(key,val)\n", + " self.size = self.size + 1\n", + "\n", + " def _put(self,key,val,currentNode):\n", + " if key < currentNode.key:\n", + " if currentNode.hasLeftChild():\n", + " self._put(key,val,currentNode.leftChild)\n", + " else:\n", + " currentNode.leftChild = TreeNode(key,val,parent=currentNode)\n", + " else:\n", + " if currentNode.hasRightChild():\n", + " self._put(key,val,currentNode.rightChild)\n", + " else:\n", + " currentNode.rightChild = TreeNode(key,val,parent=currentNode)\n", + "\n", + " def __setitem__(self,k,v):\n", + " self.put(k,v)\n", + "\n", + " def get(self,key):\n", + " if self.root:\n", + " res = self._get(key,self.root)\n", + " if res:\n", + " \n", + " return res.payload\n", + " else:\n", + " return None\n", + " else:\n", + " return None\n", + "\n", + " def _get(self,key,currentNode):\n", + " \n", + " if not currentNode:\n", + " return None\n", + " elif currentNode.key == key:\n", + " return currentNode\n", + " elif key < currentNode.key:\n", + " return self._get(key,currentNode.leftChild)\n", + " else:\n", + " return self._get(key,currentNode.rightChild)\n", + "\n", + " def __getitem__(self,key):\n", + " return self.get(key)\n", + "\n", + " def __contains__(self,key):\n", + " if self._get(key,self.root):\n", + " return True\n", + " else:\n", + " return False\n", + "\n", + " def delete(self,key):\n", + " \n", + " if self.size > 1:\n", + " \n", + " nodeToRemove = self._get(key,self.root)\n", + " if nodeToRemove:\n", + " self.remove(nodeToRemove)\n", + " self.size = self.size-1\n", + " else:\n", + " raise KeyError('Error, key not in tree')\n", + " elif self.size == 1 and self.root.key == key:\n", + " self.root = None\n", + " self.size = self.size - 1\n", + " else:\n", + " raise KeyError('Error, key not in tree')\n", + "\n", + " def __delitem__(self,key):\n", + " \n", + " self.delete(key)\n", + "\n", + " def spliceOut(self):\n", + " if self.isLeaf():\n", + " if self.isLeftChild():\n", + " \n", + " self.parent.leftChild = None\n", + " else:\n", + " self.parent.rightChild = None\n", + " elif self.hasAnyChildren():\n", + " if self.hasLeftChild():\n", + " \n", + " if self.isLeftChild():\n", + " \n", + " self.parent.leftChild = self.leftChild\n", + " else:\n", + " \n", + " self.parent.rightChild = self.leftChild\n", + " self.leftChild.parent = self.parent\n", + " else:\n", + " \n", + " if self.isLeftChild():\n", + " \n", + " self.parent.leftChild = self.rightChild\n", + " else:\n", + " self.parent.rightChild = self.rightChild\n", + " self.rightChild.parent = self.parent\n", + "\n", + " def findSuccessor(self):\n", + " \n", + " succ = None\n", + " if self.hasRightChild():\n", + " succ = self.rightChild.findMin()\n", + " else:\n", + " if self.parent:\n", + " \n", + " if self.isLeftChild():\n", + " \n", + " succ = self.parent\n", + " else:\n", + " self.parent.rightChild = None\n", + " succ = self.parent.findSuccessor()\n", + " self.parent.rightChild = self\n", + " return succ\n", + "\n", + " def findMin(self):\n", + " \n", + " current = self\n", + " while current.hasLeftChild():\n", + " current = current.leftChild\n", + " return current\n", + "\n", + " def remove(self,currentNode):\n", + " \n", + " if currentNode.isLeaf(): #leaf\n", + " if currentNode == currentNode.parent.leftChild:\n", + " currentNode.parent.leftChild = None\n", + " else:\n", + " currentNode.parent.rightChild = None\n", + " elif currentNode.hasBothChildren(): #interior\n", + " \n", + " succ = currentNode.findSuccessor()\n", + " succ.spliceOut()\n", + " currentNode.key = succ.key\n", + " currentNode.payload = succ.payload\n", + "\n", + " else: # this node has one child\n", + " if currentNode.hasLeftChild():\n", + " if currentNode.isLeftChild():\n", + " currentNode.leftChild.parent = currentNode.parent\n", + " currentNode.parent.leftChild = currentNode.leftChild\n", + " elif currentNode.isRightChild():\n", + " currentNode.leftChild.parent = currentNode.parent\n", + " currentNode.parent.rightChild = currentNode.leftChild\n", + " else:\n", + " \n", + " currentNode.replaceNodeData(currentNode.leftChild.key,\n", + " currentNode.leftChild.payload,\n", + " currentNode.leftChild.leftChild,\n", + " currentNode.leftChild.rightChild)\n", + " else:\n", + " \n", + " if currentNode.isLeftChild():\n", + " currentNode.rightChild.parent = currentNode.parent\n", + " currentNode.parent.leftChild = currentNode.rightChild\n", + " elif currentNode.isRightChild():\n", + " currentNode.rightChild.parent = currentNode.parent\n", + " currentNode.parent.rightChild = currentNode.rightChild\n", + " else:\n", + " currentNode.replaceNodeData(currentNode.rightChild.key,\n", + " currentNode.rightChild.payload,\n", + " currentNode.rightChild.leftChild,\n", + " currentNode.rightChild.rightChild)\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "yellow\n", + "at\n" + ] + } + ], + "source": [ + "mytree = BinarySearchTree()\n", + "mytree[3]=\"red\"\n", + "mytree[4]=\"blue\"\n", + "mytree[6]=\"yellow\"\n", + "mytree[2]=\"at\"\n", + "\n", + "print(mytree[6])\n", + "print(mytree[2])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "** Check the video for full explanation! **" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/Trees/Binary Search Trees.ipynb b/Trees/Binary Search Trees.ipynb index c6679bb0..04781356 100644 --- a/Trees/Binary Search Trees.ipynb +++ b/Trees/Binary Search Trees.ipynb @@ -17,9 +17,7 @@ { "cell_type": "code", "execution_count": 5, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [], "source": [ "class TreeNode:\n", @@ -249,9 +247,7 @@ { "cell_type": "code", "execution_count": 6, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -297,9 +293,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.11" + "version": "2.7.15" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } diff --git a/Trees/Trees Interview Problems - PRACTICE/bst1.png b/Trees/Trees Interview Problems - PRACTICE/bst1.png index f4a93b03..0d78250f 100644 Binary files a/Trees/Trees Interview Problems - PRACTICE/bst1.png and b/Trees/Trees Interview Problems - PRACTICE/bst1.png differ diff --git a/Trees/Trees Interview Problems - PRACTICE/bst_trim.png b/Trees/Trees Interview Problems - PRACTICE/bst_trim.png index 095025c9..35fdf8be 100644 Binary files a/Trees/Trees Interview Problems - PRACTICE/bst_trim.png and b/Trees/Trees Interview Problems - PRACTICE/bst_trim.png differ diff --git a/Trees/Trees Interview Problems - SOLUTIONS/bst1.png b/Trees/Trees Interview Problems - SOLUTIONS/bst1.png index f4a93b03..0d78250f 100644 Binary files a/Trees/Trees Interview Problems - SOLUTIONS/bst1.png and b/Trees/Trees Interview Problems - SOLUTIONS/bst1.png differ diff --git a/Trees/Trees Interview Problems - SOLUTIONS/bst_trim.png b/Trees/Trees Interview Problems - SOLUTIONS/bst_trim.png index 095025c9..35fdf8be 100644 Binary files a/Trees/Trees Interview Problems - SOLUTIONS/bst_trim.png and b/Trees/Trees Interview Problems - SOLUTIONS/bst_trim.png differ diff --git a/Trees/Trees Interview Problems/bst1.png b/Trees/Trees Interview Problems/bst1.png index f4a93b03..0d78250f 100644 Binary files a/Trees/Trees Interview Problems/bst1.png and b/Trees/Trees Interview Problems/bst1.png differ diff --git a/Trees/Trees Interview Problems/bst_trim.png b/Trees/Trees Interview Problems/bst_trim.png index 095025c9..35fdf8be 100644 Binary files a/Trees/Trees Interview Problems/bst_trim.png and b/Trees/Trees Interview Problems/bst_trim.png differ diff --git a/Untitled.ipynb b/Untitled.ipynb new file mode 100644 index 00000000..f84b2842 --- /dev/null +++ b/Untitled.ipynb @@ -0,0 +1,1098 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 0" + ] + }, + { + "cell_type": "code", + "execution_count": 572, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\n", + "class NodeKey():\n", + " def __init__(self, value, name=None):\n", + " self.name = name\n", + " self.value = value\n", + "\n", + " def __lt__(self, other):\n", + " return self.value < other.value or (self.value == other.value and self.name < other.name)\n", + "\n", + " def __le__(self, other):\n", + " return self < other or self == other\n", + "\n", + " def __eq__(self, other):\n", + " return self.value == other.value and self.name == other.name\n", + "\n", + " def __ne__(self, other):\n", + " return self.value != other.value or self.name != other.name\n", + "\n", + " def __gt__(self, other):\n", + " return self.value > other.value or (self.value == other.value and self.name > other.name)\n", + "\n", + " def __ge__(self, other):\n", + " return self > other or self == other\n", + "\n", + " def __str__(self):\n", + " if self.name is None:\n", + " return str(self.value)\n", + " else:\n", + " return str(self.value) + \",\" + str(self.name)\n", + "\n", + "\n", + "class Node():\n", + " def __init__(self, value, name=None):\n", + " self.key = NodeKey(value, name)\n", + " self.value = value\n", + " self.parent = None\n", + " self.left_child = None\n", + " self.right_child = None\n", + " self.height = 0\n", + "\n", + " def __str__(self):\n", + " return str(self.key)\n", + "\n", + " def next(self):\n", + " \"\"\" Returns the next Node (next key value larger)\n", + " \"\"\"\n", + " # If has right child, select, then traverse left all the way down\n", + " if self.right_child is not None:\n", + " node = self.right_child\n", + " while node.left_child is not None:\n", + " node = node.left_child\n", + " return node\n", + "\n", + " node = self\n", + " # Try to find an ancestor that is a left child, return parent of that\n", + " while node.parent is not None:\n", + " if node.parent.left_child == node:\n", + " return node.parent\n", + " node = node.parent\n", + "\n", + " # Nothing greater than this\n", + " return None\n", + "\n", + " def previous(self):\n", + " \"\"\" Returns the previous Node (next key value smaller)\n", + " \"\"\"\n", + " # If has left child, select, then traverse right all the way down\n", + " if self.left_child is not None:\n", + " node = self.left_child\n", + " while node.right_child is not None:\n", + " node = node.right_child\n", + " return node\n", + "\n", + " node = self\n", + " # Try to find an ancestor that is a right child, return parent of that\n", + " while node.parent is not None:\n", + " if node.parent.right_child == node:\n", + " return node.parent\n", + " node = node.parent\n", + "\n", + " # Nothing smaller than this\n", + " return None\n", + "\n", + " def is_leaf(self):\n", + " \"\"\" Return True if Leaf, False Otherwise\n", + " \"\"\"\n", + " return self.height == 0\n", + "\n", + " def max_child_height(self):\n", + " \"\"\" Return Height Of Tallest Child or -1 if No Children\n", + " \"\"\"\n", + " if self.left_child and self.right_child:\n", + " # two children\n", + " return max(self.left_child.height, self.right_child.height)\n", + " elif self.left_child is not None and self.right_child is None:\n", + " # one child, on left\n", + " return self.left_child.height\n", + " elif self.left_child is None and self.right_child is not None:\n", + " # one child, on right\n", + " return self.right_child.height\n", + " else:\n", + " # no Children\n", + " return -1\n", + "\n", + " def weigh(self):\n", + " \"\"\" Return How Left or Right Sided the Tree Is\n", + " Positive Number Means Left Side Heavy, Negative Number Means Right Side Heavy\n", + " \"\"\"\n", + " if self.left_child is None:\n", + " left_height = -1\n", + " else:\n", + " left_height = self.left_child.height\n", + "\n", + " if self.right_child is None:\n", + " right_height = -1\n", + " else:\n", + " right_height = self.right_child.height\n", + "\n", + " balance = left_height - right_height\n", + " return balance\n", + "\n", + " def update_height(self):\n", + " \"\"\" Updates Height of This Node and All Ancestor Nodes, As Necessary\n", + " \"\"\"\n", + " # TODO: should stop iterating when reaches correct height\n", + " node = self\n", + " while node is not None:\n", + " node.height = node.max_child_height() + 1\n", + " node = node.parent\n", + "\n", + " def root(self):\n", + " node = self\n", + " while node.parent is not None:\n", + " node = node.parent\n", + " return node\n", + "\n", + " def balance(self, tree):\n", + " \"\"\" Balances node, sets new tree root if appropriate\n", + " Note: If balancing does occur, this node will move to a lower position on the tree\n", + " \"\"\"\n", + " while self.weigh() < -1 or self.weigh() > 1:\n", + " if self.weigh() < 0:\n", + " # right side heavy\n", + " if self.right_child.weigh() > 0:\n", + " # right-side left-side heavy\n", + " self.right_child.rotate_left()\n", + " # right-side right-side heavy\n", + " new_top = self.rotate_right()\n", + " else:\n", + " # left side heavy\n", + " if self.left_child.weigh() < 0:\n", + " # left-side right-side heavy\n", + " self.left_child.rotate_right()\n", + " # left-side left-side heavy\n", + " new_top = self.rotate_left()\n", + "\n", + " if new_top.parent is None:\n", + " tree.root = new_top\n", + "\n", + " def out(self):\n", + " \"\"\" Return String Representing Tree From Current Node Down\n", + " Only Works for Small Trees\n", + " \"\"\"\n", + " start_node = self\n", + " space_symbol = \"*\"\n", + " spaces_count = 250\n", + " out_string = \"\"\n", + " initial_spaces_string = space_symbol * spaces_count + \"\\n\"\n", + " if start_node is None:\n", + " return \"AVLTree is empty\"\n", + " else:\n", + " level = [start_node]\n", + " while len([i for i in level if (not i is None)]) > 0:\n", + " level_string = initial_spaces_string\n", + " for i in xrange(len(level)):\n", + " j = (i + 1) * spaces_count / (len(level) + 1)\n", + " level_string = level_string[:j] + (str(level[i]) if level[i] else space_symbol) + level_string[j + 1:]\n", + " level_next = []\n", + " for i in level:\n", + " level_next += ([i.left_child, i.right_child] if i else [None, None])\n", + " level = level_next\n", + " out_string += level_string\n", + " return out_string\n", + "\n", + " def rotate_right(self):\n", + " assert(self.right_child is not None)\n", + " to_promote = self.right_child\n", + " swapper = to_promote.left_child\n", + "\n", + " # swap children\n", + " self.right_child = swapper\n", + " to_promote.left_child = self\n", + " new_top = self._swap_parents(to_promote, swapper)\n", + " if swapper is not None:\n", + " swapper.update_height()\n", + " self.update_height()\n", + " return new_top\n", + "\n", + " def rotate_left(self):\n", + " assert(self.left_child is not None)\n", + " to_promote = self.left_child\n", + " swapper = to_promote.right_child\n", + "\n", + " # swap children\n", + " self.left_child = swapper\n", + " to_promote.right_child = self\n", + " new_top = self._swap_parents(to_promote, swapper)\n", + " if swapper is not None:\n", + " swapper.update_height()\n", + " self.update_height()\n", + " return new_top\n", + "\n", + " def _swap_parents(self, promote, swapper):\n", + " \"\"\" re-assign parents, returns new top\n", + " \"\"\"\n", + " promote.parent = self.parent\n", + " self.parent = promote\n", + " if swapper is not None:\n", + " swapper.parent = self\n", + "\n", + " if promote.parent is not None:\n", + " if promote.parent.right_child == self:\n", + " promote.parent.right_child = promote\n", + " elif promote.parent.left_child == self:\n", + " promote.parent.left_child = promote\n", + " return promote\n", + "\n", + "\n", + "class BinaryTree():\n", + " \"\"\" Binary Search Tree\n", + " Uses AVL Tree\n", + " \"\"\"\n", + " def __init__(self, *args):\n", + " self.root = None # root Node\n", + " self.element_count = 0\n", + " if len(args) == 1:\n", + " for i in args[0]:\n", + " self.insert(i)\n", + "\n", + " def __len__(self):\n", + " return self.element_count\n", + "\n", + " def __str__(self):\n", + " return self.out()\n", + "\n", + " def height(self):\n", + " \"\"\" Return Max Height Of Tree\n", + " \"\"\"\n", + " if self.root:\n", + " return self.root.height\n", + " else:\n", + " return 0\n", + "\n", + " def balance(self):\n", + " \"\"\" Perform balancing Operation\n", + " \"\"\"\n", + " if self.root is not None:\n", + " self.root.balance(self)\n", + "\n", + " def insert(self, value, name=None):\n", + " if self.root is None:\n", + " # If nothing in tree\n", + " self.root = Node(value, name)\n", + " else:\n", + " if self.find(value, name) is None:\n", + " # If key/name pair doesn't exist in tree\n", + " self.element_count += 1\n", + " self.add_as_child(self.root, Node(value, name))\n", + "\n", + " def add_as_child(self, parent_node, child_node):\n", + " if child_node.key < parent_node.key:\n", + " # should go on left\n", + " if parent_node.left_child is None:\n", + " # can add to this node\n", + " parent_node.left_child = child_node\n", + " child_node.parent = parent_node\n", + " child_node.update_height()\n", + " else:\n", + " self.add_as_child(parent_node.left_child, child_node)\n", + " else:\n", + " # should go on right\n", + " if parent_node.right_child is None:\n", + " # can add to this node\n", + " parent_node.right_child = child_node\n", + " child_node.parent = parent_node\n", + " child_node.update_height()\n", + " else:\n", + " self.add_as_child(parent_node.right_child, child_node)\n", + "\n", + " if parent_node.weigh() not in [-1, 0, 1]:\n", + " parent_node.balance(self)\n", + "\n", + " def inorder_non_recursive(self):\n", + " node = self.root\n", + " retlst = []\n", + " while node.left_child:\n", + " node = node.left_child\n", + " while node:\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " if node.right_child:\n", + " node = node.right_child\n", + " while node.left_child:\n", + " node = node.left_child\n", + " else:\n", + " while node.parent and (node == node.parent.right_child):\n", + " node = node.parent\n", + " node = node.parent\n", + " return retlst\n", + "\n", + " def preorder(self, node, retlst=None):\n", + " if retlst is None:\n", + " retlst = []\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " if node.left_child:\n", + " retlst = self.preorder(node.left_child, retlst)\n", + " if node.right_child:\n", + " retlst = self.preorder(node.right_child, retlst)\n", + " return retlst\n", + "\n", + " def inorder(self, node, retlst=None):\n", + " if retlst is None:\n", + " retlst = []\n", + " if node.left_child:\n", + " retlst = self.inorder(node.left_child, retlst)\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " if node.right_child:\n", + " retlst = self.inorder(node.right_child, retlst)\n", + " return retlst\n", + "\n", + " def postorder(self, node, retlst=None):\n", + " if retlst is None:\n", + " retlst = []\n", + " if node.left_child:\n", + " retlst = self.postorder(node.left_child, retlst)\n", + " if node.right_child:\n", + " retlst = self.postorder(node.right_child, retlst)\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " return retlst\n", + "\n", + " def as_list(self, pre_in_post):\n", + " if not self.root:\n", + " return []\n", + " if pre_in_post == 0:\n", + " return self.preorder(self.root)\n", + " elif pre_in_post == 1:\n", + " return self.inorder(self.root)\n", + " elif pre_in_post == 2:\n", + " return self.postorder(self.root)\n", + " elif pre_in_post == 3:\n", + " return self.inorder_non_recursive()\n", + "\n", + " def find(self, value, name=None):\n", + " return self.find_in_subtree(self.root, NodeKey(value, name))\n", + "\n", + " def find_in_subtree(self, node, node_key):\n", + " if node is None:\n", + " return None # key not found\n", + " if node_key < node.key:\n", + " return self.find_in_subtree(node.left_child, node_key)\n", + " elif node_key > node.key:\n", + " return self.find_in_subtree(node.right_child, node_key)\n", + " else: # key is equal to node key\n", + " return node\n", + "\n", + " def remove(self, key):\n", + " # first find\n", + " node = self.find(key)\n", + "\n", + " if not node is None:\n", + " self.element_count -= 1\n", + "\n", + " if node.is_leaf():\n", + " # The node is a leaf. Remove it and return.\n", + " self.remove_leaf(node)\n", + " elif (node.left_child is not None and node.right_child is None) or (node.left_child is None and node.right_child is not None):\n", + " # The node has only 1 child. Make the pointer to this node point to the child of this node.\n", + " self.remove_branch(node)\n", + " else:\n", + " # The node has 2 children. Swap items with the successor (the smallest item in its right subtree) and\n", + " # delete the successor from the right subtree of the node.\n", + " assert node.left_child and node.right_child\n", + " self.swap_with_successor_and_remove(node)\n", + "\n", + " def remove_leaf(self, node):\n", + " parent = node.parent\n", + " if parent:\n", + " if parent.left_child == node:\n", + " parent.left_child = None\n", + " else:\n", + " assert (parent.right_child == node)\n", + " parent.right_child = None\n", + " parent.update_height()\n", + " else:\n", + " self.root = None\n", + "\n", + " # rebalance\n", + " node = parent\n", + " while node:\n", + " if not node.weigh() in [-1, 0, 1]:\n", + " node.balance(self)\n", + " node = node.parent\n", + "\n", + " def remove_branch(self, node):\n", + " parent = node.parent\n", + " if parent:\n", + " if parent.left_child == node:\n", + " parent.left_child = node.right_child or node.left_child\n", + " else:\n", + " assert (parent.right_child == node)\n", + " parent.right_child = node.right_child or node.left_child\n", + "\n", + " if node.left_child:\n", + " node.left_child.parent = parent\n", + " else:\n", + " assert node.right_child\n", + " node.right_child.parent = parent\n", + " parent.update_height()\n", + "\n", + " # rebalance\n", + " node = parent\n", + " while node:\n", + " if not node.weigh() in [-1, 0, 1]:\n", + " node.balance(self)\n", + " node = node.parent\n", + "\n", + " def swap_with_successor_and_remove(self, node):\n", + " successor = node.right_child\n", + " while successor.left_child:\n", + " successor = successor.left_child\n", + " self.swap_nodes(node, successor)\n", + " assert (node.left_child is None)\n", + " if node.height == 0:\n", + " self.remove_leaf(node)\n", + " else:\n", + " self.remove_branch(node)\n", + "\n", + " def swap_nodes(self, node_1, node_2):\n", + " assert (node_1.height > node_2.height)\n", + " parent_1 = node_1.parent\n", + " left_child_1 = node_1.left_child\n", + " right_child_1 = node_1.right_child\n", + " parent_2 = node_2.parent\n", + " assert (not parent_2 is None)\n", + " assert (parent_2.left_child == node_2 or parent_2 == node_1)\n", + " left_child_2 = node_2.left_child\n", + " assert (left_child_2 is None)\n", + " right_child_2 = node_2.right_child\n", + "\n", + " # swap heights\n", + " tmp = node_1.height\n", + " node_1.height = node_2.height\n", + " node_2.height = tmp\n", + "\n", + " if parent_1:\n", + " if parent_1.left_child == node_1:\n", + " parent_1.left_child = node_2\n", + " else:\n", + " assert (parent_1.right_child == node_1)\n", + " parent_1.right_child = node_2\n", + " node_2.parent = parent_1\n", + " else:\n", + " self.root = node_2\n", + " node_2.parent = None\n", + "\n", + " node_2.left_child = left_child_1\n", + " left_child_1.parent = node_2\n", + " node_1.left_child = left_child_2 # None\n", + " node_1.right_child = right_child_2\n", + " if right_child_2:\n", + " right_child_2.parent = node_1\n", + " if not (parent_2 == node_1):\n", + " node_2.right_child = right_child_1\n", + " right_child_1.parent = node_2\n", + "\n", + " parent_2.left_child = node_1\n", + " node_1.parent = parent_2\n", + " else:\n", + " node_2.right_child = node_1\n", + " node_1.parent = node_2\n", + "\n", + " # use for debug only and only with small trees\n", + "\n", + " def out(self, start_node=None):\n", + " if start_node is None:\n", + " start_node = self.root\n", + "\n", + " if start_node is None:\n", + " return None\n", + " else:\n", + " return start_node.out()\n", + "\n", + "\n", + " def find_closest_to_the_left_strict(self,node_tmp,new_node_find):\n", + " if not node_tmp:\n", + " return None\n", + " if node_tmp.key >= new_node_find:\n", + " left_node_result = self.find_closest_to_the_left_strict(node_tmp.left_child,new_node_find)\n", + " if left_node_result:\n", + " return left_node_result\n", + " else:\n", + " return None\n", + " else:\n", + " right_node_result = self.find_closest_to_the_left_strict(node_tmp.right_child,new_node_find)\n", + " if right_node_result:\n", + " return right_node_result\n", + " else:\n", + " return node_tmp\n", + "\n", + " def find_closest_to_the_left_strict_value_only(self,value):\n", + " return self.find_closest_to_the_left_strict(self.root,NodeKey(value))\n", + "\n", + " def find_closest_to_the_right_strict(self,node_tmp,new_node_find):\n", + " if not node_tmp:\n", + " return None\n", + " if node_tmp.key > new_node_find:\n", + " left_node_result = self.find_closest_to_the_right_strict(node_tmp.left_child,new_node_find)\n", + " if left_node_result:\n", + " return left_node_result\n", + " else:\n", + " return node_tmp\n", + " else:\n", + " right_node_result = self.find_closest_to_the_right_strict(node_tmp.right_child,new_node_find)\n", + " if right_node_result:\n", + " return right_node_result\n", + " else:\n", + " return None\n", + "\n", + " def find_closest_to_the_right_strict_value_only(self,value):\n", + " return self.find_closest_to_the_right_strict(self.root,NodeKey(value))\n", + "\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 587, + "metadata": {}, + "outputs": [], + "source": [ + "btree = BinaryTree()" + ] + }, + { + "cell_type": "code", + "execution_count": 588, + "metadata": {}, + "outputs": [], + "source": [ + "for i in range(1000):\n", + " rand_now = random.randint(0,100)\n", + "\n", + " btree.insert(rand_now)\n", + "btree.insert(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 589, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]\n" + ] + } + ], + "source": [ + "print btree.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 590, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.Node instance at 0x7f678efbd098>" + ] + }, + "execution_count": 590, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree.find(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 591, + "metadata": {}, + "outputs": [], + "source": [ + "btree.remove(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 592, + "metadata": {}, + "outputs": [], + "source": [ + "btree.find(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 593, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]\n" + ] + } + ], + "source": [ + "print btree.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 585, + "metadata": {}, + "outputs": [], + "source": [ + "sorted_btree_list = btree.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 563, + "metadata": {}, + "outputs": [], + "source": [ + "root_node_now = btree.root" + ] + }, + { + "cell_type": "code", + "execution_count": 564, + "metadata": {}, + "outputs": [], + "source": [ + "new_node_find = NodeKey(14)" + ] + }, + { + "cell_type": "code", + "execution_count": 565, + "metadata": {}, + "outputs": [], + "source": [ + "node_tmp = root_node_now" + ] + }, + { + "cell_type": "code", + "execution_count": 566, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9" + ] + }, + "execution_count": 566, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree.find_closest_to_the_left_strict_value_only(10).value" + ] + }, + { + "cell_type": "code", + "execution_count": 567, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 567, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "btree.find_closest_to_the_left_strict_value_only(10.1).value" + ] + }, + { + "cell_type": "code", + "execution_count": 568, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]\n" + ] + } + ], + "source": [ + "print btree.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 569, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12" + ] + }, + "execution_count": 569, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree.find_closest_to_the_right_strict_value_only(10.1).value" + ] + }, + { + "cell_type": "code", + "execution_count": 570, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "13" + ] + }, + "execution_count": 570, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree.find_closest_to_the_right_strict_value_only(12).value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 571, + "metadata": {}, + "outputs": [], + "source": [ + "def find_closest_to_the_left_strict(node_tmp,new_node_find):\n", + " if not node_tmp:\n", + " return None\n", + " if node_tmp.key >= new_node_find:\n", + " left_node_result = find_closest_to_the_left_strict(node_tmp.left_child,new_node_find)\n", + " if left_node_result:\n", + " return left_node_result\n", + " else:\n", + " return None \n", + " else:\n", + " right_node_result = find_closest_to_the_left_strict(node_tmp.right_child,new_node_find)\n", + " if right_node_result:\n", + " return right_node_result\n", + " else:\n", + " return node_tmp" + ] + }, + { + "cell_type": "code", + "execution_count": 547, + "metadata": {}, + "outputs": [], + "source": [ + "def find_closest_to_the_right_strict(node_tmp,new_node_find):\n", + " if not node_tmp:\n", + " return None\n", + " if node_tmp.key > new_node_find:\n", + " left_node_result = find_closest_to_the_right_strict(node_tmp.left_child,new_node_find)\n", + " if left_node_result:\n", + " return left_node_result\n", + " else:\n", + " return node_tmp \n", + " else:\n", + " right_node_result = find_closest_to_the_right_strict(node_tmp.right_child,new_node_find)\n", + " if right_node_result:\n", + " return right_node_result\n", + " else:\n", + " return None" + ] + }, + { + "cell_type": "code", + "execution_count": 548, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "59" + ] + }, + "execution_count": 548, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result_59 = find_closest_to_the_right_strict(btree.root,NodeKey(58.1))\n", + "result_59.value" + ] + }, + { + "cell_type": "code", + "execution_count": 515, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "60" + ] + }, + "execution_count": 515, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result_60 = find_closest_to_the_right_strict(btree.root,NodeKey(59))\n", + "result_60.value" + ] + }, + { + "cell_type": "code", + "execution_count": 519, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "78" + ] + }, + "execution_count": 519, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result_60 = find_closest_to_the_right_strict(btree.root,NodeKey(77))\n", + "result_60.value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 516, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "58" + ] + }, + "execution_count": 516, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result_58 = find_closest_to_the_left_strict(btree.root,NodeKey(58.1))\n", + "result_58.value" + ] + }, + { + "cell_type": "code", + "execution_count": 517, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9" + ] + }, + "execution_count": 517, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result_58 = find_closest_to_the_left_strict(btree.root,NodeKey(9.1))\n", + "result_58.value" + ] + }, + { + "cell_type": "code", + "execution_count": 518, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "8" + ] + }, + "execution_count": 518, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result_58 = find_closest_to_the_left_strict(btree.root,NodeKey(9))\n", + "result_58.value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Untitled1.ipynb b/Untitled1.ipynb new file mode 100644 index 00000000..92cd123b --- /dev/null +++ b/Untitled1.ipynb @@ -0,0 +1,4389 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# import binary search tree dict" + ] + }, + { + "cell_type": "code", + "execution_count": 445, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def binary_search_left_on_sorted_array(array, target,cmp = None, mode= None):\n", + " # tell if we can find the target, if yes, return, True, and one element, otherwise\n", + " \"\"\"\n", + " \"\"\"\n", + " lower = 0\n", + " upper = len(array)\n", + " succeed = False\n", + "\n", + " while lower < upper:\n", + " x = lower + (upper - lower) // 2\n", + " val = array[x]\n", + " if cmp is None:\n", + " if target == val:\n", + " if mode == None:\n", + " succeed = True\n", + " break\n", + " elif target > val:\n", + " if lower == x:\n", + "\n", + " break\n", + " lower = x\n", + " elif target < val:\n", + " upper = x\n", + " else:\n", + " if cmp(target,val) == 0:\n", + " succeed = True\n", + " break\n", + " elif cmp(target,val) == 1:\n", + " if lower == x:\n", + " break\n", + " lower = x\n", + " elif cmp(target,val) == -1:\n", + " upper = x\n", + "\n", + " if cmp is None:\n", + " lowest_larger_than_target = array[lower] > target\n", + " else:\n", + " if cmp(target, array[lower]) == -1:\n", + " lowest_larger_than_target = True\n", + "\n", + " if succeed:\n", + " return succeed, x\n", + " elif not succeed and array[lower] > target:\n", + " return succeed, -1\n", + " else:\n", + " return succeed, lower\n", + "\n", + "def simple_insort(array,x,cmp=None,mode= None):\n", + " \"\"\"Insert item x in list a, and keep it sorted assuming a is sorted.\n", + " \"\"\"\n", + " found_element, idx_on_the_left =binary_search_left_on_sorted_array(array,x,cmp,mode)\n", + " where_to_insert = idx_on_the_left + 1\n", + " array.insert(where_to_insert, x)\n", + " return where_to_insert\n", + "\n", + "\n", + "\n", + "def bisect_right(a, x, lo=0, hi=None, cmp = None):\n", + " \"\"\"Return the index where to insert item x in list a, assuming a is sorted.\n", + " The return value i is such that all e in a[:i] have e <= x, and all e in\n", + " a[i:] have e > x. So if x already appears in the list, a.insert(x) will\n", + " insert just after the rightmost x already there.\n", + " Optional args lo (default 0) and hi (default len(a)) bound the\n", + " slice of a to be searched.\n", + " \"\"\"\n", + "\n", + " if lo < 0:\n", + " raise ValueError('lo must be non-negative')\n", + " if hi is None:\n", + " hi = len(a)\n", + " while lo < hi:\n", + " mid = (lo+hi)//2\n", + " if not cmp is None:\n", + " if cmp(x,a[mid])==-1: hi = mid\n", + " else: lo = mid+1\n", + " else:\n", + " if x < a[mid]: hi = mid\n", + " else: lo = mid+1\n", + "\n", + " if not cmp is None:\n", + " if cmp(x,a[lo-1])==0:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + " else:\n", + " if a[lo-1]== x:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + "\n", + " return lo, matched\n", + "\n", + "def bisect_left(a, x, lo=0, hi=None, cmp = None):\n", + " \"\"\"Return the index where to insert item x in list a, assuming a is sorted.\n", + " The return value i is such that all e in a[:i] have e < x, and all e in\n", + " a[i:] have e >= x. So if x already appears in the list, a.insert(x) will\n", + " insert just before the leftmost x already there.\n", + " Optional args lo (default 0) and hi (default len(a)) bound the\n", + " slice of a to be searched.\n", + " \"\"\"\n", + "\n", + " if lo < 0:\n", + " raise ValueError('lo must be non-negative')\n", + " if hi is None:\n", + " hi = len(a)\n", + "\n", + " hi_record = hi\n", + " while lo < hi:\n", + " mid = (lo+hi)//2\n", + "\n", + " if not cmp is None:\n", + " if a[mid] < x: lo = mid+1\n", + " else: hi = mid\n", + " else:\n", + " if a[mid] < x: lo = mid+1\n", + " else: hi = mid\n", + "\n", + " if lo >= hi_record:\n", + " matched=False\n", + " else:\n", + " if not cmp is None:\n", + " if cmp(x,a[lo])==0:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + " else:\n", + " if a[lo]== x:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + "\n", + "\n", + "\n", + " return lo, matched\n", + "\n", + "def insort_right(a, x, lo=0, hi=None,cmp = None):\n", + " \"\"\"Insert item x in list a, and keep it sorted assuming a is sorted.\n", + " If x is already in a, insert it to the right of the rightmost x.\n", + " Optional args lo (default 0) and hi (default len(a)) bound the\n", + " slice of a to be searched.\n", + " \"\"\"\n", + " lo, matched = bisect_right(a, x, lo, hi, cmp)\n", + " a.insert(lo, x)\n", + " return lo\n", + "\n", + "def insort_left(a, x, lo=0, hi=None,cmp = None):\n", + " \"\"\"Insert item x in list a, and keep it sorted assuming a is sorted.\n", + " If x is already in a, insert it to the left of the leftmost x.\n", + " Optional args lo (default 0) and hi (default len(a)) bound the\n", + " slice of a to be searched.\n", + " \"\"\"\n", + " lo, matched = bisect_left(a, x, lo, hi, cmp)\n", + " a.insert(lo, x)\n", + " return lo\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 447, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "\n", + "def bisect_right(a, x, lo=0, hi=None, cmp = None):\n", + " \"\"\"Return the index where to insert item x in list a, assuming a is sorted.\n", + " The return value i is such that all e in a[:i] have e <= x, and all e in\n", + " a[i:] have e > x. So if x already appears in the list, a.insert(x) will\n", + " insert just after the rightmost x already there.\n", + " Optional args lo (default 0) and hi (default len(a)) bound the\n", + " slice of a to be searched.\n", + " \"\"\"\n", + "\n", + " if lo < 0:\n", + " raise ValueError('lo must be non-negative')\n", + " if hi is None:\n", + " hi = len(a)\n", + " while lo < hi:\n", + " mid = (lo+hi)//2\n", + " if not cmp is None:\n", + " if cmp(x,a[mid])==-1: hi = mid\n", + " else: lo = mid+1\n", + " else:\n", + " if x < a[mid]: hi = mid\n", + " else: lo = mid+1\n", + "\n", + " if not cmp is None:\n", + " if cmp(x,a[lo-1])==0:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + " else:\n", + " if a[lo-1]== x:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + "\n", + " return lo, matched\n", + "\n", + "def bisect_left(a, x, lo=0, hi=None, cmp = None):\n", + " \"\"\"Return the index where to insert item x in list a, assuming a is sorted.\n", + " The return value i is such that all e in a[:i] have e < x, and all e in\n", + " a[i:] have e >= x. So if x already appears in the list, a.insert(x) will\n", + " insert just before the leftmost x already there.\n", + " Optional args lo (default 0) and hi (default len(a)) bound the\n", + " slice of a to be searched.\n", + " \"\"\"\n", + "\n", + " if lo < 0:\n", + " raise ValueError('lo must be non-negative')\n", + " if hi is None:\n", + " hi = len(a)\n", + "\n", + " hi_record = hi\n", + " while lo < hi:\n", + " mid = (lo+hi)//2\n", + "\n", + " if not cmp is None:\n", + " if a[mid] < x: lo = mid+1\n", + " else: hi = mid\n", + " else:\n", + " if a[mid] < x: lo = mid+1\n", + " else: hi = mid\n", + "\n", + " if lo >= hi_record:\n", + " matched=False\n", + " else:\n", + " if not cmp is None:\n", + " if cmp(x,a[lo])==0:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + " else:\n", + " if a[lo]== x:\n", + " matched = True\n", + " else:\n", + " matched = False\n", + "\n", + "\n", + "\n", + " return lo, matched\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "\n", + "class NodeKey():\n", + " def __init__(self, value, name=None):\n", + " self.name = name\n", + " self.value = value\n", + "\n", + " def __lt__(self, other):\n", + " return self.value < other.value or (self.value == other.value and self.name < other.name)\n", + "\n", + " def __le__(self, other):\n", + " return self < other or self == other\n", + "\n", + " def __eq__(self, other):\n", + " return self.value == other.value and self.name == other.name\n", + "\n", + " def __ne__(self, other):\n", + " return self.value != other.value or self.name != other.name\n", + "\n", + " def __gt__(self, other):\n", + " return self.value > other.value or (self.value == other.value and self.name > other.name)\n", + "\n", + " def __ge__(self, other):\n", + " return self > other or self == other\n", + "\n", + " def __str__(self):\n", + " if self.name is None:\n", + " return str(self.value)\n", + " else:\n", + " return str(self.value) + \",\" + str(self.name)\n", + "\n", + "\n", + "class Node():\n", + " def __init__(self, value, name=None):\n", + " self.key = NodeKey(value, name)\n", + " self.value = value\n", + " self.parent = None\n", + " self.left_child = None\n", + " self.right_child = None\n", + " self.height = 0\n", + "\n", + " def __str__(self):\n", + " return str(self.key)\n", + "\n", + " def next(self):\n", + " \"\"\" Returns the next Node (next key value larger)\n", + " \"\"\"\n", + " # If has right child, select, then traverse left all the way down\n", + " if self.right_child is not None:\n", + " node = self.right_child\n", + " while node.left_child is not None:\n", + " node = node.left_child\n", + " return node\n", + "\n", + " node = self\n", + " # Try to find an ancestor that is a left child, return parent of that\n", + " while node.parent is not None:\n", + " if node.parent.left_child == node:\n", + " return node.parent\n", + " node = node.parent\n", + "\n", + " # Nothing greater than this\n", + " return None\n", + "\n", + " def previous(self):\n", + " \"\"\" Returns the previous Node (next key value smaller)\n", + " \"\"\"\n", + " # If has left child, select, then traverse right all the way down\n", + " if self.left_child is not None:\n", + " node = self.left_child\n", + " while node.right_child is not None:\n", + " node = node.right_child\n", + " return node\n", + "\n", + " node = self\n", + " # Try to find an ancestor that is a right child, return parent of that\n", + " while node.parent is not None:\n", + " if node.parent.right_child == node:\n", + " return node.parent\n", + " node = node.parent\n", + "\n", + " # Nothing smaller than this\n", + " return None\n", + "\n", + " def is_leaf(self):\n", + " \"\"\" Return True if Leaf, False Otherwise\n", + " \"\"\"\n", + " return self.height == 0\n", + "\n", + " def max_child_height(self):\n", + " \"\"\" Return Height Of Tallest Child or -1 if No Children\n", + " \"\"\"\n", + " if self.left_child and self.right_child:\n", + " # two children\n", + " return max(self.left_child.height, self.right_child.height)\n", + " elif self.left_child is not None and self.right_child is None:\n", + " # one child, on left\n", + " return self.left_child.height\n", + " elif self.left_child is None and self.right_child is not None:\n", + " # one child, on right\n", + " return self.right_child.height\n", + " else:\n", + " # no Children\n", + " return -1\n", + "\n", + " def weigh(self):\n", + " \"\"\" Return How Left or Right Sided the Tree Is\n", + " Positive Number Means Left Side Heavy, Negative Number Means Right Side Heavy\n", + " \"\"\"\n", + " if self.left_child is None:\n", + " left_height = -1\n", + " else:\n", + " left_height = self.left_child.height\n", + "\n", + " if self.right_child is None:\n", + " right_height = -1\n", + " else:\n", + " right_height = self.right_child.height\n", + "\n", + " balance = left_height - right_height\n", + " return balance\n", + "\n", + " def update_height(self):\n", + " \"\"\" Updates Height of This Node and All Ancestor Nodes, As Necessary\n", + " \"\"\"\n", + " # TODO: should stop iterating when reaches correct height\n", + " node = self\n", + " while node is not None:\n", + " node.height = node.max_child_height() + 1\n", + " node = node.parent\n", + "\n", + " def root(self):\n", + " node = self\n", + " while node.parent is not None:\n", + " node = node.parent\n", + " return node\n", + "\n", + " def balance(self, tree):\n", + " \"\"\" Balances node, sets new tree root if appropriate\n", + " Note: If balancing does occur, this node will move to a lower position on the tree\n", + " \"\"\"\n", + " while self.weigh() < -1 or self.weigh() > 1:\n", + " if self.weigh() < 0:\n", + " # right side heavy\n", + " if self.right_child.weigh() > 0:\n", + " # right-side left-side heavy\n", + " self.right_child.rotate_left()\n", + " # right-side right-side heavy\n", + " new_top = self.rotate_right()\n", + " else:\n", + " # left side heavy\n", + " if self.left_child.weigh() < 0:\n", + " # left-side right-side heavy\n", + " self.left_child.rotate_right()\n", + " # left-side left-side heavy\n", + " new_top = self.rotate_left()\n", + "\n", + " if new_top.parent is None:\n", + " tree.root = new_top\n", + "\n", + " def out(self):\n", + " \"\"\" Return String Representing Tree From Current Node Down\n", + " Only Works for Small Trees\n", + " \"\"\"\n", + " start_node = self\n", + " space_symbol = \"*\"\n", + " spaces_count = 250\n", + " out_string = \"\"\n", + " initial_spaces_string = space_symbol * spaces_count + \"\\n\"\n", + " if start_node is None:\n", + " return \"AVLTree is empty\"\n", + " else:\n", + " level = [start_node]\n", + " while len([i for i in level if (not i is None)]) > 0:\n", + " level_string = initial_spaces_string\n", + " for i in xrange(len(level)):\n", + " j = (i + 1) * spaces_count / (len(level) + 1)\n", + " level_string = level_string[:j] + (str(level[i]) if level[i] else space_symbol) + level_string[j + 1:]\n", + " level_next = []\n", + " for i in level:\n", + " level_next += ([i.left_child, i.right_child] if i else [None, None])\n", + " level = level_next\n", + " out_string += level_string\n", + " return out_string\n", + "\n", + " def rotate_right(self):\n", + " assert(self.right_child is not None)\n", + " to_promote = self.right_child\n", + " swapper = to_promote.left_child\n", + "\n", + " # swap children\n", + " self.right_child = swapper\n", + " to_promote.left_child = self\n", + " new_top = self._swap_parents(to_promote, swapper)\n", + " if swapper is not None:\n", + " swapper.update_height()\n", + " self.update_height()\n", + " return new_top\n", + "\n", + " def rotate_left(self):\n", + " assert(self.left_child is not None)\n", + " to_promote = self.left_child\n", + " swapper = to_promote.right_child\n", + "\n", + " # swap children\n", + " self.left_child = swapper\n", + " to_promote.right_child = self\n", + " new_top = self._swap_parents(to_promote, swapper)\n", + " if swapper is not None:\n", + " swapper.update_height()\n", + " self.update_height()\n", + " return new_top\n", + "\n", + " def _swap_parents(self, promote, swapper):\n", + " \"\"\" re-assign parents, returns new top\n", + " \"\"\"\n", + " promote.parent = self.parent\n", + " self.parent = promote\n", + " if swapper is not None:\n", + " swapper.parent = self\n", + "\n", + " if promote.parent is not None:\n", + " if promote.parent.right_child == self:\n", + " promote.parent.right_child = promote\n", + " elif promote.parent.left_child == self:\n", + " promote.parent.left_child = promote\n", + " return promote\n", + "\n", + "\n", + "class BinaryTree():\n", + " \"\"\" Binary Search Tree\n", + " Uses AVL Tree\n", + " \"\"\"\n", + " def __init__(self, *args):\n", + " self.root = None # root Node\n", + " self.element_count = 0\n", + " if len(args) == 1:\n", + " for i in args[0]:\n", + " self.insert(i)\n", + "\n", + " def __len__(self):\n", + " return self.element_count\n", + "\n", + " def __str__(self):\n", + " return self.out()\n", + "\n", + " def height(self):\n", + " \"\"\" Return Max Height Of Tree\n", + " \"\"\"\n", + " if self.root:\n", + " return self.root.height\n", + " else:\n", + " return 0\n", + "\n", + " def balance(self):\n", + " \"\"\" Perform balancing Operation\n", + " \"\"\"\n", + " if self.root is not None:\n", + " self.root.balance(self)\n", + "\n", + " def insert(self, value, name=None):\n", + " if self.root is None:\n", + " # If nothing in tree\n", + " self.root = Node(value, name)\n", + " else:\n", + " if self.find(value, name) is None:\n", + " # If key/name pair doesn't exist in tree\n", + " self.element_count += 1\n", + " self.add_as_child(self.root, Node(value, name))\n", + "\n", + " def add_as_child(self, parent_node, child_node):\n", + " if child_node.key < parent_node.key:\n", + " # should go on left\n", + " if parent_node.left_child is None:\n", + " # can add to this node\n", + " parent_node.left_child = child_node\n", + " child_node.parent = parent_node\n", + " child_node.update_height()\n", + " else:\n", + " self.add_as_child(parent_node.left_child, child_node)\n", + " else:\n", + " # should go on right\n", + " if parent_node.right_child is None:\n", + " # can add to this node\n", + " parent_node.right_child = child_node\n", + " child_node.parent = parent_node\n", + " child_node.update_height()\n", + " else:\n", + " self.add_as_child(parent_node.right_child, child_node)\n", + "\n", + " if parent_node.weigh() not in [-1, 0, 1]:\n", + " parent_node.balance(self)\n", + "\n", + " def inorder_non_recursive(self):\n", + " node = self.root\n", + " retlst = []\n", + " while node.left_child:\n", + " node = node.left_child\n", + " while node:\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " if node.right_child:\n", + " node = node.right_child\n", + " while node.left_child:\n", + " node = node.left_child\n", + " else:\n", + " while node.parent and (node == node.parent.right_child):\n", + " node = node.parent\n", + " node = node.parent\n", + " return retlst\n", + "\n", + " def preorder(self, node, retlst=None):\n", + " if retlst is None:\n", + " retlst = []\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " if node.left_child:\n", + " retlst = self.preorder(node.left_child, retlst)\n", + " if node.right_child:\n", + " retlst = self.preorder(node.right_child, retlst)\n", + " return retlst\n", + "\n", + " def inorder(self, node, retlst=None):\n", + " if retlst is None:\n", + " retlst = []\n", + " if node.left_child:\n", + " retlst = self.inorder(node.left_child, retlst)\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " if node.right_child:\n", + " retlst = self.inorder(node.right_child, retlst)\n", + " return retlst\n", + "\n", + " def postorder(self, node, retlst=None):\n", + " if retlst is None:\n", + " retlst = []\n", + " if node.left_child:\n", + " retlst = self.postorder(node.left_child, retlst)\n", + " if node.right_child:\n", + " retlst = self.postorder(node.right_child, retlst)\n", + " if node.key.name is not None:\n", + " retlst.append([node.key.value, node.key.name])\n", + " else:\n", + " retlst.append(node.key.value)\n", + " return retlst\n", + "\n", + " def as_list(self, pre_in_post):\n", + " if not self.root:\n", + " return []\n", + " if pre_in_post == 0:\n", + " return self.preorder(self.root)\n", + " elif pre_in_post == 1:\n", + " return self.inorder(self.root)\n", + " elif pre_in_post == 2:\n", + " return self.postorder(self.root)\n", + " elif pre_in_post == 3:\n", + " return self.inorder_non_recursive()\n", + "\n", + " def find(self, value, name=None):\n", + " return self.find_in_subtree(self.root, NodeKey(value, name))\n", + "\n", + " def find_in_subtree(self, node, node_key):\n", + " if node is None:\n", + " return None # key not found\n", + " if node_key < node.key:\n", + " return self.find_in_subtree(node.left_child, node_key)\n", + " elif node_key > node.key:\n", + " return self.find_in_subtree(node.right_child, node_key)\n", + " else: # key is equal to node key\n", + " return node\n", + "\n", + " def remove(self, key):\n", + " # first find\n", + " node = self.find(key)\n", + "\n", + " if not node is None:\n", + " self.element_count -= 1\n", + "\n", + " if node.is_leaf():\n", + " # The node is a leaf. Remove it and return.\n", + " self.remove_leaf(node)\n", + " elif (node.left_child is not None and node.right_child is None) or (node.left_child is None and node.right_child is not None):\n", + " # The node has only 1 child. Make the pointer to this node point to the child of this node.\n", + " self.remove_branch(node)\n", + " else:\n", + " # The node has 2 children. Swap items with the successor (the smallest item in its right subtree) and\n", + " # delete the successor from the right subtree of the node.\n", + " assert node.left_child and node.right_child\n", + " self.swap_with_successor_and_remove(node)\n", + "\n", + " def remove_leaf(self, node):\n", + " parent = node.parent\n", + " if parent:\n", + " if parent.left_child == node:\n", + " parent.left_child = None\n", + " else:\n", + " assert (parent.right_child == node)\n", + " parent.right_child = None\n", + " parent.update_height()\n", + " else:\n", + " self.root = None\n", + "\n", + " # rebalance\n", + " node = parent\n", + " while node:\n", + " if not node.weigh() in [-1, 0, 1]:\n", + " node.balance(self)\n", + " node = node.parent\n", + "\n", + " def remove_branch(self, node):\n", + " parent = node.parent\n", + " if parent:\n", + " if parent.left_child == node:\n", + " parent.left_child = node.right_child or node.left_child\n", + " else:\n", + " assert (parent.right_child == node)\n", + " parent.right_child = node.right_child or node.left_child\n", + "\n", + " if node.left_child:\n", + " node.left_child.parent = parent\n", + " else:\n", + " assert node.right_child\n", + " node.right_child.parent = parent\n", + " parent.update_height()\n", + "\n", + " # rebalance\n", + " node = parent\n", + " while node:\n", + " if not node.weigh() in [-1, 0, 1]:\n", + " node.balance(self)\n", + " node = node.parent\n", + "\n", + " def swap_with_successor_and_remove(self, node):\n", + " successor = node.right_child\n", + " while successor.left_child:\n", + " successor = successor.left_child\n", + " self.swap_nodes(node, successor)\n", + " assert (node.left_child is None)\n", + " if node.height == 0:\n", + " self.remove_leaf(node)\n", + " else:\n", + " self.remove_branch(node)\n", + "\n", + " def swap_nodes(self, node_1, node_2):\n", + " assert (node_1.height > node_2.height)\n", + " parent_1 = node_1.parent\n", + " left_child_1 = node_1.left_child\n", + " right_child_1 = node_1.right_child\n", + " parent_2 = node_2.parent\n", + " assert (not parent_2 is None)\n", + " assert (parent_2.left_child == node_2 or parent_2 == node_1)\n", + " left_child_2 = node_2.left_child\n", + " assert (left_child_2 is None)\n", + " right_child_2 = node_2.right_child\n", + "\n", + " # swap heights\n", + " tmp = node_1.height\n", + " node_1.height = node_2.height\n", + " node_2.height = tmp\n", + "\n", + " if parent_1:\n", + " if parent_1.left_child == node_1:\n", + " parent_1.left_child = node_2\n", + " else:\n", + " assert (parent_1.right_child == node_1)\n", + " parent_1.right_child = node_2\n", + " node_2.parent = parent_1\n", + " else:\n", + " self.root = node_2\n", + " node_2.parent = None\n", + "\n", + " node_2.left_child = left_child_1\n", + " left_child_1.parent = node_2\n", + " node_1.left_child = left_child_2 # None\n", + " node_1.right_child = right_child_2\n", + " if right_child_2:\n", + " right_child_2.parent = node_1\n", + " if not (parent_2 == node_1):\n", + " node_2.right_child = right_child_1\n", + " right_child_1.parent = node_2\n", + "\n", + " parent_2.left_child = node_1\n", + " node_1.parent = parent_2\n", + " else:\n", + " node_2.right_child = node_1\n", + " node_1.parent = node_2\n", + "\n", + " # use for debug only and only with small trees\n", + "\n", + " def out(self, start_node=None):\n", + " if start_node is None:\n", + " start_node = self.root\n", + "\n", + " if start_node is None:\n", + " return None\n", + " else:\n", + " return start_node.out()\n", + "\n", + "\n", + " def find_closest_to_the_left_strict(self,node_tmp,new_node_find):\n", + " if not node_tmp:\n", + " return None\n", + " if node_tmp.key >= new_node_find:\n", + " left_node_result = self.find_closest_to_the_left_strict(node_tmp.left_child,new_node_find)\n", + " if left_node_result:\n", + " return left_node_result\n", + " else:\n", + " return None\n", + " else:\n", + " right_node_result = self.find_closest_to_the_left_strict(node_tmp.right_child,new_node_find)\n", + " if right_node_result:\n", + " return right_node_result\n", + " else:\n", + " return node_tmp\n", + "\n", + " def find_closest_to_the_left_strict_value_only(self,value):\n", + " return self.find_closest_to_the_left_strict(self.root,NodeKey(value))\n", + "\n", + " def find_closest_to_the_right_strict(self,node_tmp,new_node_find):\n", + " if not node_tmp:\n", + " return None\n", + " if node_tmp.key > new_node_find:\n", + " left_node_result = self.find_closest_to_the_right_strict(node_tmp.left_child,new_node_find)\n", + " if left_node_result:\n", + " return left_node_result\n", + " else:\n", + " return node_tmp\n", + " else:\n", + " right_node_result = self.find_closest_to_the_right_strict(node_tmp.right_child,new_node_find)\n", + " if right_node_result:\n", + " return right_node_result\n", + " else:\n", + " return None\n", + "\n", + " def find_closest_to_the_right_strict_value_only(self,value):\n", + " return self.find_closest_to_the_right_strict(self.root,NodeKey(value))\n", + "\n", + "\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# redo Q1" + ] + }, + { + "cell_type": "code", + "execution_count": 501, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "list_now = [423,231,5134,21332]" + ] + }, + { + "cell_type": "code", + "execution_count": 502, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "heapq.heapify(list_now)" + ] + }, + { + "cell_type": "code", + "execution_count": 503, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[231, 423, 5134, 21332]" + ] + }, + "execution_count": 503, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list_now" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 499, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "#!/bin/python\n", + "\n", + "import math\n", + "import os\n", + "import random\n", + "import re\n", + "import sys\n", + "\n", + "import heapq" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 550, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n", + "09:30:00 1 b 100 l 9.99\n", + "09:31:00 2 b 1000 l 9.95\n", + "09:32:00 3 s 100 l 10.01\n", + "09:33:00 4 s 1000 l 10.05\n", + "09:41:00 5 b 200 m -1.00\n" + ] + } + ], + "source": [ + "input_1 = raw_input()\n", + "input_1 = int(input_1)\n", + "list_of_lines = []\n", + "for i in range(input_1):\n", + " input_2 = raw_input()\n", + " list_of_lines.append(input_2)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 583, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:42:00 6 s 200 m -1.00\")" + ] + }, + { + "cell_type": "code", + "execution_count": 594, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:43:00 7 b 200 l 11\")" + ] + }, + { + "cell_type": "code", + "execution_count": 608, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:44:00 8 s 200 m -1\")" + ] + }, + { + "cell_type": "code", + "execution_count": 621, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:45:00 8 s 1000 m -1\")" + ] + }, + { + "cell_type": "code", + "execution_count": 640, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "\n", + "list_of_lines.append(\"09:45:00 8 s 500 l 25\")" + ] + }, + { + "cell_type": "code", + "execution_count": 641, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:45:00 8 b 800 l 25\")" + ] + }, + { + "cell_type": "code", + "execution_count": 646, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:46:00 9 b 100 l 35\")" + ] + }, + { + "cell_type": "code", + "execution_count": 649, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:47:00 10 b 700 l 35\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 653, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:48:00 11 b 200 l 0.33\")\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 657, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:49:00 12 b 1000 m -1.00\")\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 660, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:50:00 4 s 1000 l 10.05\")\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 664, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "list_of_lines.append(\"09:51:00 12 b 10000 m -1.00\")\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 665, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['09:30:00 1 b 100 l 9.99',\n", + " '09:31:00 2 b 1000 l 9.95',\n", + " '09:32:00 3 s 100 l 10.01',\n", + " '09:33:00 4 s 1000 l 10.05',\n", + " '09:41:00 5 b 200 m -1.00',\n", + " '09:42:00 6 s 200 m -1.00',\n", + " '09:43:00 7 b 200 l 11',\n", + " '09:44:00 8 s 200 m -1',\n", + " '09:45:00 8 s 1000 m -1',\n", + " '09:45:00 8 s 500 l 25',\n", + " '09:45:00 8 b 800 l 25',\n", + " '09:46:00 9 b 100 l 35',\n", + " '09:47:00 10 b 700 l 35',\n", + " '09:48:00 11 b 200 l 0.33',\n", + " '09:49:00 12 b 1000 m -1.00',\n", + " '09:50:00 4 s 1000 l 10.05',\n", + " '09:51:00 12 b 10000 m -1.00']" + ] + }, + "execution_count": 665, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list_of_lines" + ] + }, + { + "cell_type": "code", + "execution_count": 639, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'09:45:00 8 s 1000 l 700'" + ] + }, + "execution_count": 639, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list_of_lines.pop()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 666, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "09:41:00 5 3 10.01 100\n", + "09:41:00 5 4 10.05 100\n", + "09:42:00 6 1 9.99 100\n", + "09:42:00 6 2 9.95 100\n", + "09:43:00 7 4 10.05 200\n", + "09:44:00 8 2 9.95 200\n", + "09:45:00 8 2 9.95 700\n", + "09:45:00 8 4 10.05 700\n", + "09:45:00 8 8 25.00 100\n", + "09:46:00 9 8 25.00 100\n", + "09:47:00 10 8 25.00 300\n", + "09:50:00 4 10 35.00 400\n", + "09:51:00 12 4 10.05 600\n" + ] + } + ], + "source": [ + "\"\"\"ask heap is min heap (standard) containing (price,id,amount) \n", + "and bid heap is max heap but implemented with min heap where each element is\n", + "(-price,id,amount) \"\"\"\n", + "string_to_print = \"\"\n", + "bid_heap = []\n", + "ask_heap = []\n", + "\n", + "for i in range(len(list_of_lines)):\n", + " \n", + " line_now = list_of_lines[i]\n", + " splited_line = line_now.split(\" \")\n", + " time_stamp = splited_line[0]\n", + " id_now = int(splited_line[1])\n", + " buy_or_sell = splited_line[2]\n", + " amount = int(splited_line[3])\n", + " limit_or_market = splited_line[4]\n", + " limit_price = float(splited_line[5])\n", + "\n", + " limit_or_market_original = limit_or_market\n", + "\n", + " if limit_or_market == \"m\":\n", + " \"\"\"if it is market order, just consider it as a limit order with infinite\n", + " limit price for buy and 0 limit price for sell\"\"\"\n", + " limit_or_market = \"l\"\n", + " if buy_or_sell == \"b\":\n", + " limit_price = float(\"infinity\")\n", + " if buy_or_sell == \"s\":\n", + " limit_price = 0 \n", + "\n", + "\n", + " if limit_or_market == \"l\":\n", + " if buy_or_sell == \"b\":\n", + " \"\"\"look into btree_ask\"\"\"\n", + " order_remaining = amount\n", + " \"\"\"firstly see if any amount can be filled \"\"\"\n", + " price_now = None\n", + " if len(ask_heap)>0:\n", + " if ask_heap[0][0] <= limit_price:\n", + " price_now = ask_heap[0][0]\n", + " \n", + " while price_now != None and len(ask_heap)>0 and order_remaining>0:\n", + " _, id_in_the_book, amount_in_the_book = ask_heap[0]\n", + " amount_filled = min(order_remaining,amount_in_the_book)\n", + " order_remaining = order_remaining - amount_filled\n", + " string_tmp = time_stamp + \" \" + str(id_now) + \" \" + str(id_in_the_book) + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " print string_tmp\n", + " if amount_filled == amount_in_the_book:\n", + " heapq.heappop(ask_heap)\n", + " else:\n", + " ask_heap[0] = (price_now, id_in_the_book, amount_in_the_book - amount_filled)\n", + " price_now = None\n", + " if len(ask_heap)>0:\n", + " if ask_heap[0][0] <= limit_price:\n", + " price_now = ask_heap[0][0]\n", + "\n", + " \"\"\"post buy order in bid_heap\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + " heapq.heappush(bid_heap,(-limit_price,id_now,order_remaining))\n", + " \n", + " if buy_or_sell == \"s\":\n", + " \"\"\"look into btree_ask\"\"\"\n", + " order_remaining = amount\n", + " \"\"\"firstly see if any amount can be filled \"\"\"\n", + " price_now = None\n", + " if len(bid_heap)>0:\n", + " if -bid_heap[0][0] >= limit_price: #-bid_heap[0] is the price, so that bid the top pops out\n", + " price_now = -bid_heap[0][0]\n", + "\n", + "\n", + " while price_now != None and len(bid_heap)>0 and order_remaining>0: \n", + " _, id_in_the_book, amount_in_the_book = bid_heap[0]\n", + " amount_filled = min(order_remaining,amount_in_the_book)\n", + " order_remaining = order_remaining - amount_filled\n", + " string_tmp = time_stamp + \" \" + str(id_now) + \" \" + str(id_in_the_book) + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " print string_tmp\n", + " if amount_filled == amount_in_the_book:\n", + " heapq.heappop(bid_heap)\n", + " else:\n", + " bid_heap[0] = (-price_now, id_in_the_book, amount_in_the_book - amount_filled)\n", + " price_now = None\n", + " if len(bid_heap)>0:\n", + " if -bid_heap[0][0] >= limit_price: #-bid_heap[0] is the price, so that bid the top pops out\n", + " price_now = -bid_heap[0][0]\n", + "\n", + "\n", + " \"\"\"post sell order in ask_heap\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + " heapq.heappush(ask_heap,(limit_price,id_now,order_remaining))\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 667, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[(-0.33, 11, 200)]\n", + "[]\n" + ] + } + ], + "source": [ + " print bid_heap\n", + " print ask_heap\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 615, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 615, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(bid_heap)>0" + ] + }, + { + "cell_type": "code", + "execution_count": 616, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "-9.95" + ] + }, + "execution_count": 616, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "-bid_heap[0][0]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 613, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "IndentationError", + "evalue": "expected an indented block (, line 2)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m \u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m expected an indented block\n" + ] + } + ], + "source": [ + " if len(bid_heap)>0:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 605, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(9.95, 2, 900)]" + ] + }, + "execution_count": 605, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bid_heap" + ] + }, + { + "cell_type": "code", + "execution_count": 606, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(10.05, 4, 700)]" + ] + }, + "execution_count": 606, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ask_heap" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 563, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "TypeError", + "evalue": "float argument required, not NoneType", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mtime_stamp\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mid_now\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mid_in_the_book\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m\"%.2f\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0mprice_now\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mamount_filled\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mTypeError\u001b[0m: float argument required, not NoneType" + ] + } + ], + "source": [ + "time_stamp + \" \" + str(id_now) + \" \" + str(id_in_the_book) + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 513, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "ename": "TypeError", + "evalue": "cannot concatenate 'str' and 'int' objects", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mtime_stamp\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mid_now\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mid_in_the_book\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m\"%.2f\"\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0mprice_now\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m\" \"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mamount_filled\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m: cannot concatenate 'str' and 'int' objects" + ] + } + ], + "source": [ + " time_stamp + \" \" + str(id_now) + \" \" + id_in_the_book + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled)" + ] + }, + { + "cell_type": "code", + "execution_count": 509, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "10.01" + ] + }, + "execution_count": 509, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "limit_price" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# final product" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#!/bin/python\n", + "\n", + "import math\n", + "import os\n", + "import random\n", + "import re\n", + "import sys\n", + "import heapq\n", + "\n", + "input_1 = raw_input()\n", + "input_1 = int(input_1)\n", + "list_of_lines = []\n", + "for i in range(input_1):\n", + " input_2 = raw_input()\n", + " list_of_lines.append(input_2)\n", + "\n", + "\n", + "\"\"\"ask heap is min heap (standard) containing (price,id,amount) \n", + "and bid heap is max heap but implemented with min heap where each element is\n", + "(-price,id,amount) \"\"\"\n", + "string_to_print = \"\"\n", + "bid_heap = []\n", + "ask_heap = []\n", + "\n", + "for i in range(len(list_of_lines)):\n", + " \n", + " line_now = list_of_lines[i]\n", + " splited_line = line_now.split(\" \")\n", + " time_stamp = splited_line[0]\n", + " id_now = int(splited_line[1])\n", + " buy_or_sell = splited_line[2]\n", + " amount = int(splited_line[3])\n", + " limit_or_market = splited_line[4]\n", + " limit_price = float(splited_line[5])\n", + "\n", + " limit_or_market_original = limit_or_market\n", + "\n", + " if limit_or_market == \"m\":\n", + " \"\"\"if it is market order, just consider it as a limit order with infinite\n", + " limit price for buy and 0 limit price for sell\"\"\"\n", + " limit_or_market = \"l\"\n", + " if buy_or_sell == \"b\":\n", + " limit_price = float(\"infinity\")\n", + " if buy_or_sell == \"s\":\n", + " limit_price = 0 \n", + "\n", + "\n", + " if limit_or_market == \"l\":\n", + " if buy_or_sell == \"b\":\n", + " \"\"\"look into btree_ask\"\"\"\n", + " order_remaining = amount\n", + " \"\"\"firstly see if any amount can be filled \"\"\"\n", + " price_now = None\n", + " if len(ask_heap)>0:\n", + " if ask_heap[0][0] <= limit_price:\n", + " price_now = ask_heap[0][0]\n", + " \n", + " while price_now != None and len(ask_heap)>0 and order_remaining>0:\n", + " _, id_in_the_book, amount_in_the_book = ask_heap[0]\n", + " amount_filled = min(order_remaining,amount_in_the_book)\n", + " order_remaining = order_remaining - amount_filled\n", + " string_tmp = time_stamp + \" \" + str(id_now) + \" \" + str(id_in_the_book) + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " print string_tmp\n", + " if amount_filled == amount_in_the_book:\n", + " heapq.heappop(ask_heap)\n", + " else:\n", + " ask_heap[0] = (price_now, id_in_the_book, amount_in_the_book - amount_filled)\n", + " price_now = None\n", + " if len(ask_heap)>0:\n", + " if ask_heap[0][0] <= limit_price:\n", + " price_now = ask_heap[0][0]\n", + "\n", + " \"\"\"post buy order in bid_heap\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + " heapq.heappush(bid_heap,(-limit_price,id_now,order_remaining))\n", + " \n", + " if buy_or_sell == \"s\":\n", + " \"\"\"look into btree_ask\"\"\"\n", + " order_remaining = amount\n", + " \"\"\"firstly see if any amount can be filled \"\"\"\n", + " price_now = None\n", + " if len(bid_heap)>0:\n", + " if -bid_heap[0][0] >= limit_price: #-bid_heap[0] is the price, so that bid the top pops out\n", + " price_now = -bid_heap[0][0]\n", + "\n", + "\n", + " while price_now != None and len(bid_heap)>0 and order_remaining>0: \n", + " _, id_in_the_book, amount_in_the_book = bid_heap[0]\n", + " amount_filled = min(order_remaining,amount_in_the_book)\n", + " order_remaining = order_remaining - amount_filled\n", + " string_tmp = time_stamp + \" \" + str(id_now) + \" \" + str(id_in_the_book) + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " print string_tmp\n", + " if amount_filled == amount_in_the_book:\n", + " heapq.heappop(bid_heap)\n", + " else:\n", + " bid_heap[0] = (-price_now, id_in_the_book, amount_in_the_book - amount_filled)\n", + " price_now = None\n", + " if len(bid_heap)>0:\n", + " if -bid_heap[0][0] >= limit_price: #-bid_heap[0] is the price, so that bid the top pops out\n", + " price_now = -bid_heap[0][0]\n", + "\n", + "\n", + " \"\"\"post sell order in ask_heap\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + " heapq.heappush(ask_heap,(limit_price,id_now,order_remaining))\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# real Q1\n" + ] + }, + { + "cell_type": "code", + "execution_count": 483, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "import heapq" + ] + }, + { + "cell_type": "code", + "execution_count": 490, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "list_now = [1,3,2,4,2,13,1]" + ] + }, + { + "cell_type": "code", + "execution_count": 493, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "heapq.heapify(list_now)" + ] + }, + { + "cell_type": "code", + "execution_count": 494, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 2, 1, 4, 3, 13, 2]" + ] + }, + "execution_count": 494, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list_now" + ] + }, + { + "cell_type": "code", + "execution_count": 496, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "heapq.heappush(list_now,10)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 481, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n", + "09:30:00 1 b 100 l 9.99\n", + "09:31:00 2 b 1000 l 9.95\n", + "09:32:00 3 s 100 l 10.01\n", + "09:33:00 4 s 1000 l 10.05\n", + "09:41:00 5 b 200 m -1.00\n" + ] + } + ], + "source": [ + " input_1 = raw_input()\n", + " input_1 = int(input_1)\n", + " list_of_lines = []\n", + " for i in range(input_1):\n", + " input_2 = raw_input()\n", + " list_of_lines.append(input_2)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "string_to_print = \"\"\n", + "\n", + "\"\"\"this hash table is used to associate with each bid/ask with its avaialble offer in sequence\n", + "we will use queue here, an implemention from python is with deque(a bit more expensive)\n", + "\"\"\"\n", + "\"\"\"I realized there is issue in my binary search tree code. I cannot Tree.find after I Tree.search\"\"\"\n", + "\"\"\"i don't know of other built in binary search in python and I don't have time to rebuilt \n", + "my previous binary tree , so I have to use a less efficient method with sorted list\"\"\"\n", + "bid_hash = {}\n", + "ask_hash = {}\n", + "btree_bid = BinaryTree()\n", + "btree_ask = BinaryTree()\n", + "sorted_list_bid = []\n", + "sorted_list_ask = []" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 482, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "here\n", + "here\n" + ] + }, + { + "ename": "KeyError", + "evalue": "9.99", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 123\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0mprice_now\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0morder_remaining\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 124\u001b[0;31m \u001b[0mbid_hash_value_deque_now\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mask_hash\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mprice_now\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 125\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbid_hash_value_deque_now\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;36m0\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0morder_remaining\u001b[0m\u001b[0;34m>\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 126\u001b[0m \u001b[0mthe_id_amount_to_examine\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mbid_hash_value_deque_now\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: 9.99" + ] + } + ], + "source": [ + "for i in range(input_1):\n", + " line_now = list_of_lines[i]\n", + " splited_line = line_now.split(\" \")\n", + "\n", + " time_stamp = splited_line[0]\n", + " id_now = splited_line[1]\n", + " buy_or_sell = splited_line[2]\n", + " amount = int(splited_line[3])\n", + " limit_or_market = splited_line[4]\n", + " limit_price = float(splited_line[5])\n", + "\n", + " limit_or_market_original = limit_or_market\n", + "\n", + " if limit_or_market == \"m\":\n", + " \"\"\"if it is market order, just consider it as a limit order with 0\n", + " limit price for buy and infinite limit price for sell\"\"\"\n", + " limit_or_market = \"l\"\n", + " if buy_or_sell == \"b\":\n", + " limit_price = 0\n", + " if buy_or_sell == \"s\":\n", + " limit_price = float(\"infinity\")\n", + "\n", + "\n", + "\n", + " if limit_or_market == \"l\":\n", + " if buy_or_sell == \"b\":\n", + " print \"here\"\n", + " \"\"\"look into btree_ask\"\"\"\n", + " order_remaining = amount\n", + " \"\"\"firstly see if any amount can be filled \"\"\"\n", + " price_now = None\n", + " lo, matched = bisect_left(sorted_list_ask,limit_price)\n", + " if matched:\n", + " price_now = sorted_list_bid[lo]\n", + " elif lo+1 < len(sorted_list_ask):\n", + " price_now = sorted_list_ask[lo + 1]\n", + " \n", + "# if btree_ask.find(limit_price):\n", + "# price_now = limit_price\n", + "# else:\n", + "# node_now = btree_ask.find_closest_to_the_right_strict_value_only(limit_price)\n", + "# if node_now:\n", + "# price_now = node_now.value\n", + "\n", + " while price_now != None and order_remaining>0:\n", + " ask_hash_value_deque_now = ask_hash[price_now]\n", + " while len(ask_hash_value_deque_now)>0 and order_remaining>0:\n", + " the_id_amount_to_examine = ask_hash_value_deque_now[0]\n", + " id_in_the_book = the_id_amount_to_examine[0]\n", + " amount_in_the_book = the_id_amount_to_examine[1]\n", + " amount_filled = min(order_remaining,amount_in_the_book)\n", + " order_remaining = order_remaining - amount_filled\n", + " string_tmp = time_stamp + \" \" + id_now + \" \" + id_in_the_book + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " string_to_print += string_tmp\n", + " print string_tmp\n", + " if amount_filled == amount_in_the_book:\n", + " ask_hash_value_deque_now.popleft()\n", + " if len(ask_hash_value_deque_now) == 0 :\n", + " del ask_hash[price_now]\n", + "# btree_ask.remove(price_now)\n", + " lo, matched = bisect_left(sorted_list_ask,limit_price)\n", + " sorted_list_ask.remove(lo)\n", + " else:\n", + " ask_hash_value_deque_now[0][1] = amount_in_the_book - amount_filled\n", + " price_now = None\n", + " lo, matched = bisect_left(sorted_list_ask,limit_price)\n", + " if matched:\n", + " price_now = sorted_list_bid[lo]\n", + " elif lo+1 < len(sorted_list_ask):\n", + " price_now = sorted_list_ask[lo + 1]\n", + "\n", + "# node_now = btree_ask.find_closest_to_the_right_strict_value_only(limit_price)\n", + "# if node_now:\n", + "# price_now = node_now.value\n", + "\n", + "\n", + " \"\"\"post buy order in btree_bid\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + " \"\"\"tree is more efficient\"\"\"\n", + "# btree_bid.insert(limit_price)\n", + " insort_left(sorted_list_bid,limit_price)\n", + " if limit_price in bid_hash:\n", + " bid_hash[limit_price].append([id_now,order_remaining])\n", + " else:\n", + " bid_hash[limit_price] = deque()\n", + " bid_hash[limit_price].append([id_now,order_remaining]) \n", + "\n", + " if buy_or_sell == \"s\":\n", + " order_remaining = amount\n", + " price_now = None\n", + " lo, matched = bisect_left(sorted_list_bid,limit_price)\n", + " if matched:\n", + " price_now = sorted_list_bid[lo]\n", + " elif lo -1 >= 0:\n", + " price_now = sorted_list_bid[lo-1]\n", + "\n", + " \n", + "# if btree_bid.find(limit_price):\n", + "# price_now = limit_price\n", + "# else:\n", + "# node_now = btree_bid.find_closest_to_the_left_strict_value_only(limit_price)\n", + "# if node_now:\n", + "# price_now = node_now.value\n", + "\n", + " while price_now != None and order_remaining>0:\n", + " bid_hash_value_deque_now = ask_hash[price_now]\n", + " while len(bid_hash_value_deque_now)>0 and order_remaining>0:\n", + " the_id_amount_to_examine = bid_hash_value_deque_now[0]\n", + " id_in_the_book = the_id_amount_to_examine[0]\n", + " amount_in_the_book = the_id_amount_to_examine[1]\n", + " amount_filled = min(order_remaining,amount_in_the_book)\n", + " order_remaining = order_remaining - amount_filled\n", + " string_tmp = time_stamp + \" \" + id_now + \" \" + id_in_the_book + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " string_to_print += string_tmp\n", + " print string_tmp\n", + " if amount_filled == amount_in_the_book:\n", + " bid_hash_value_deque_now.popleft()\n", + " if len(bid_hash_value_deque_now) == 0 :\n", + " del bid_hash[price_now]\n", + " \"\"\"this is designed to work, but due to some issue, it does not work for now, I will need more time to debug into it \"\"\"\n", + "# btree_bid.remove(price_now)\n", + " lo, matched = bisect_left(sorted_list_bid,limit_price)\n", + " sorted_list_bid.remove(lo)\n", + " else:\n", + " ask_hash_value_deque_now[0][1] = amount_in_the_book - amount_filled\n", + " price_now = None\n", + " lo, matched = bisect_left(sorted_list_bid,limit_price)\n", + " if matched:\n", + " price_now = sorted_list_bid[lo]\n", + " elif lo -1 >= 0:\n", + " price_now = sorted_list_bid[lo-1]\n", + "\n", + " \"\"\"below is more efficient but there is bug\"\"\"\n", + "# node_now = btree_bid.find_closest_to_the_left_strict_value_only(limit_price)\n", + "# if node_now:\n", + "# price_now = node_now.value\n", + "\n", + " \n", + " \n", + " \"\"\"post sell order in btree_ask\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + "# print \"inserting \"+str(limit_price)\n", + " insort_left(sorted_list_ask,limit_price)\n", + "# btree_ask.insert(limit_price)\n", + " if limit_price in ask_hash:\n", + " ask_hash[limit_price].append([id_now,order_remaining])\n", + " else:\n", + " ask_hash[limit_price] = deque()\n", + " ask_hash[limit_price].append([id_now,order_remaining]) " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 336, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree = BinaryTree()" + ] + }, + { + "cell_type": "code", + "execution_count": 347, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "for i in range(1000):\n", + " rand_now = random.randint(0,100)\n", + "\n", + " btree.insert(rand_now)\n", + "btree.insert(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 348, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]\n" + ] + } + ], + "source": [ + "print btree.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 349, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.Node instance at 0x7fabdefd10e0>" + ] + }, + "execution_count": 349, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree.find(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 350, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree.remove(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 351, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree.find(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 352, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]\n" + ] + } + ], + "source": [ + "print btree.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 353, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + " btree.insert(11.1)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 354, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11.1, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]\n" + ] + } + ], + "source": [ + "print btree.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 355, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree.remove(11.1)" + ] + }, + { + "cell_type": "code", + "execution_count": 356, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]\n" + ] + } + ], + "source": [ + "print btree.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 357, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[10.01, 10.05]" + ] + }, + "execution_count": 357, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 358, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.Node instance at 0x7fabec0245a8>" + ] + }, + "execution_count": 358, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.find(10.01)" + ] + }, + { + "cell_type": "code", + "execution_count": 359, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree_ask.remove(10.01)" + ] + }, + { + "cell_type": "code", + "execution_count": 360, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "<__main__.Node instance at 0x7fabec0245a8>" + ] + }, + "execution_count": 360, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.find(10.01)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 335, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[10.01, 10.05]" + ] + }, + "execution_count": 335, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 317, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{10.05: deque([['4', 1000]])}" + ] + }, + "execution_count": 317, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ask_hash" + ] + }, + { + "cell_type": "code", + "execution_count": 313, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "10.01" + ] + }, + "execution_count": 313, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "price_now" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 290, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "i = i + 1" + ] + }, + { + "cell_type": "code", + "execution_count": 291, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "\n", + "line_now = list_of_lines[i]\n", + "splited_line = line_now.split(\" \")\n", + "\n", + "time_stamp = splited_line[0]\n", + "id_now = splited_line[1]\n", + "buy_or_sell = splited_line[2]\n", + "amount = int(splited_line[3])\n", + "limit_or_market = splited_line[4]\n", + "limit_price = float(splited_line[5])\n", + "\n", + "limit_or_market_original = limit_or_market\n", + "\n", + "if limit_or_market == \"m\":\n", + " \"\"\"if it is market order, just consider it as a limit order with 0\n", + " limit price for buy and infinite limit price for sell\"\"\"\n", + " limit_or_market = \"l\"\n", + " if buy_or_sell == \"b\":\n", + " limit_price = 0\n", + " if buy_or_sell == \"s\":\n", + " limit_price = float(\"infinity\")\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 292, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "here\n" + ] + } + ], + "source": [ + " if limit_or_market == \"l\":\n", + " if buy_or_sell == \"b\":\n", + " print \"here\"\n", + " \"\"\"look into btree_ask\"\"\"\n", + " order_remaining = amount\n", + " \"\"\"firstly see if any amount can be filled \"\"\"\n", + " # condition_that_the_order_cannot_be_filled_at_all = btree_ask.find(limit_price) == None and btree_ask.find_closest_to_the_right_strict_value_only(limit_price) == None: \n", + " # node_for_limit_price = btree_ask.find(limit_price)\n", + " # if node_for_limit_price:\n", + " price_now = None\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 293, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + " if btree_ask.find(limit_price):\n", + " price_now = limit_price\n", + " else:\n", + " node_now = btree_ask.find_closest_to_the_right_strict_value_only(limit_price)\n", + " if node_now:\n", + " price_now = node_now.value\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 294, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "10.01" + ] + }, + "execution_count": 294, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "price_now" + ] + }, + { + "cell_type": "code", + "execution_count": 295, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 295, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "price_now != None and order_remaining>0" + ] + }, + { + "cell_type": "code", + "execution_count": 296, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "ask_hash_value_deque_now = ask_hash[price_now]\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 297, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "deque([['3', 100]])" + ] + }, + "execution_count": 297, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ask_hash_value_deque_now" + ] + }, + { + "cell_type": "code", + "execution_count": 298, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "09:41:00 5 3 10.01 100\n" + ] + } + ], + "source": [ + "the_id_amount_to_examine = ask_hash_value_deque_now[0]\n", + "id_in_the_book = the_id_amount_to_examine[0]\n", + "amount_in_the_book = the_id_amount_to_examine[1]\n", + "amount_filled = min(order_remaining,amount_in_the_book)\n", + "order_remaining = order_remaining - amount_filled\n", + "string_tmp = time_stamp + \" \" + id_now + \" \" + id_in_the_book + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + "string_to_print += string_tmp\n", + "print string_tmp\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 262, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree_ask.find(limit_price)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 265, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{9.95: deque([['2', 1000]]), 9.99: deque([['1', 100]])}" + ] + }, + "execution_count": 265, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bid_hash" + ] + }, + { + "cell_type": "code", + "execution_count": 266, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[9.95, 9.99]" + ] + }, + "execution_count": 266, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_bid.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 267, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{10.01: deque([['3', 100]]), 10.05: deque([['4', 1000]])}" + ] + }, + "execution_count": 267, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ask_hash" + ] + }, + { + "cell_type": "code", + "execution_count": 268, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[10.01, 10.05]" + ] + }, + "execution_count": 268, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# debug history" + ] + }, + { + "cell_type": "code", + "execution_count": 265, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{9.95: deque([['2', 1000]]), 9.99: deque([['1', 100]])}" + ] + }, + "execution_count": 265, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bid_hash" + ] + }, + { + "cell_type": "code", + "execution_count": 266, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[9.95, 9.99]" + ] + }, + "execution_count": 266, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_bid.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 267, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{10.01: deque([['3', 100]]), 10.05: deque([['4', 1000]])}" + ] + }, + "execution_count": 267, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ask_hash" + ] + }, + { + "cell_type": "code", + "execution_count": 268, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[10.01, 10.05]" + ] + }, + "execution_count": 268, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 206, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "splited_line = line_now.split(\" \")" + ] + }, + { + "cell_type": "code", + "execution_count": 207, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "time_stamp = splited_line[0]\n", + "id_now = splited_line[1]\n", + "buy_or_sell = splited_line[2]\n", + "amount = int(splited_line[3])\n", + "limit_or_market = splited_line[4]\n", + "limit_price = float(splited_line[5])" + ] + }, + { + "cell_type": "code", + "execution_count": 208, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "limit_or_market_original = limit_or_market" + ] + }, + { + "cell_type": "code", + "execution_count": 215, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "if limit_or_market == \"m\":\n", + " \"\"\"if it is market order, just consider it as a limit order with 0\n", + " limit price for buy and infinite limit price for sell\"\"\"\n", + " limit_or_market = \"l\"\n", + " if buy_or_sell == \"b\":\n", + " limit_price = 0\n", + " if buy_or_sell == \"s\":\n", + " limit_price = float(\"infinity\")\n", + "\n", + "\n", + "\n", + "if limit_or_market == \"l\":\n", + " if buy_or_sell == \"b\":\n", + " print \"here\"\n", + " \"\"\"look into btree_ask\"\"\"\n", + " order_remaining = amount\n", + " \"\"\"firstly see if any amount can be filled \"\"\"\n", + "# condition_that_the_order_cannot_be_filled_at_all = btree_ask.find(limit_price) == None and btree_ask.find_closest_to_the_right_strict_value_only(limit_price) == None: \n", + "# node_for_limit_price = btree_ask.find(limit_price)\n", + "# if node_for_limit_price:\n", + " price_now = None\n", + " if btree_ask.find(limit_price):\n", + " price_now = limit_price\n", + " else:\n", + " node_now = btree_ask.find_closest_to_the_right_strict_value_only(limit_price)\n", + " if node_now:\n", + " price_now = node_now.value\n", + "\n", + " while price_now != None and order_remaining>0:\n", + " bid_hash_value_deque_now = bid_hash[limit_price]\n", + " while len(bid_hash_value_deque_now)>0 and order_remaining>0:\n", + " the_id_amount_to_examine = bid_hash_value_deque_now[0]\n", + " id_in_the_book = the_id_amount_to_examine[0]\n", + " amount_in_the_book = the_id_amount_to_examine[1]\n", + " amount_filled = min(order_remaining,amount_in_the_book)\n", + " order_remaining = order_remaining - amount_filled\n", + " string_tmp = time_stamp + \" \" + id_now + \" \" + id_in_the_book + \" \" + (\"%.2f\" % price_now) + \" \" + str(amount_filled) \n", + " string_to_print += string_tmp\n", + " print string_tmp\n", + " if amount_filled == amount_in_the_book:\n", + " bid_hash_value_deque_now.deque_tmp.popleft()\n", + " if len(bid_hash_value_deque_now) == 0 :\n", + " btree_ask.remove(price_now)\n", + " ask_hash.remove(price_now)\n", + " else:\n", + " bid_hash_value_deque_now[0][1] = amount_in_the_book - amount_filled\n", + " price_now = None\n", + " if btree_ask.find(limit_price):\n", + " price_now = limit_price\n", + " else:\n", + " price_now = btree_ask.find_closest_to_the_right_strict_value_only(limit_price).value\n", + " \n", + " \"\"\"post buy order in btree_bid\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + " btree_bid.insert(limit_price)\n", + " if limit_price in bid_hash:\n", + " bid_hash[limit_price].append([id_now,order_remaining])\n", + " else:\n", + " bid_hash[limit_price] = deque()\n", + " bid_hash[limit_price].append([id_now,order_remaining]) \n", + " \n", + " \n", + " \n", + " if buy_or_sell == \"s\":\n", + " order_remaining = amount\n", + "\n", + " \n", + " \"\"\"post sell order in btree_ask\"\"\" \n", + " if limit_or_market_original == \"l\":\n", + " if order_remaining > 0:\n", + " btree_ask.insert(limit_price)\n", + " if limit_price in bid_hash:\n", + " ask_hash[limit_price].append([id_now,order_remaining])\n", + " else:\n", + " ask_hash[limit_price] = deque()\n", + " ask_hash[limit_price].append([id_now,order_remaining]) \n", + "\n", + " \n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 178, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[9.99, 100.0]" + ] + }, + "execution_count": 178, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_bid.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 179, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{9.99: deque([['1', 100.0], ['1', 100.0]])}" + ] + }, + "execution_count": 179, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bid_hash" + ] + }, + { + "cell_type": "code", + "execution_count": 158, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 158, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.as_list(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 159, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree_ask.insert(2)" + ] + }, + { + "cell_type": "code", + "execution_count": 163, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "node_now = btree_ask.find_closest_to_the_right_strict_value_only(1.99).value" + ] + }, + { + "cell_type": "code", + "execution_count": 164, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 164, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_now.value" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 100, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "btree_ask.root == None" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + " \"\"\"post buy order in btree_bid\"\"\" \n", + " \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree_bid.insert(limit_price)\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 118, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "if limit_price in bid_hash:\n", + " bid_hash[limit_price].append([id_now,order_remaining])\n", + "else:\n", + " bid_hash[limit_price] = deque()\n", + " bid_hash[limit_price].append([id_now,order_remaining])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 129, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "deque_tmp = deque()" + ] + }, + { + "cell_type": "code", + "execution_count": 130, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "deque_tmp.append([id_now,order_remaining])" + ] + }, + { + "cell_type": "code", + "execution_count": 131, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "deque_tmp[0][1] = 20" + ] + }, + { + "cell_type": "code", + "execution_count": 132, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "deque([['1', 20]])" + ] + }, + "execution_count": 132, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "deque_tmp" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n" + ] + } + ], + "source": [ + "if btree_ask.find(limit_price) == None:\n", + " print 2" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "100.0" + ] + }, + "execution_count": 116, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "order_remaining" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n" + ] + } + ], + "source": [ + "if btree_ask.find_closest_to_the_right_strict_value_only(limit_price) == None:\n", + " print 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + " if btree_ask.root == None:\n", + " to_fill_bid_book = True\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree_ask" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree_ask.fi" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "if limit_or_market == \"m\":\n", + " pass" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "btree_now.insert()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "input_1" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'09:41:00 5 b 200 m -1.00'" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "input_2" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['09:41:00', '5', 'b', '200', 'm', '-1.00']" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "input_2.split(\" \")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# Q1" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "#!/bin/python\n", + "\n", + "import math\n", + "import os\n", + "import random\n", + "import re\n", + "import sys\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# fptr = open(os.environ['OUTPUT_PATH'], 'w')\n", + "\n", + "arr_count = int(raw_input().strip())\n", + "\n", + "arr = []\n", + "\n", + "for _ in xrange(arr_count):\n", + " arr_item = int(raw_input().strip())\n", + " arr.append(arr_item)\n", + "\n", + "k = int(raw_input().strip())" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n", + "2\n", + "3\n", + "1\n", + "5\n" + ] + }, + { + "ename": "NameError", + "evalue": "name 'findNumber' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mk\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mraw_input\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstrip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 13\u001b[0;31m \u001b[0mres\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfindNumber\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mk\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 14\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0mfptr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m'\\n'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'findNumber' is not defined" + ] + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "if k in arr:\n", + " print \"YES\"" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def findNumber(arr, k):\n", + " if k in arr:\n", + " print \"YES\"\n", + " return \"YES\"\n", + " else:\n", + " print \"NO\"\n", + " return \"NO\"" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[2, 3, 1]" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "arr" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "k" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "NO\n" + ] + } + ], + "source": [ + "res = findNumber(arr, k)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "fptr.write(res + '\\n')\n", + "\n", + "fptr.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# Q2" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n", + "9\n" + ] + } + ], + "source": [ + " l = int(raw_input().strip())\n", + "\n", + " r = int(raw_input().strip())\n" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "def oddNumbers(l, r):\n", + " if l%2 == 1 :\n", + " #i is odd\n", + " array = range(l,r+1,2)\n", + " else:\n", + " array = range(l+1,r+1,2)\n", + "\n", + "\n", + " return array" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "initial = i" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[3, 5, 7, 9]" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "array" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[3, 5, 7, 9]" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "l%2" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "8\n" + ] + } + ], + "source": [ + "for i in range(3,9):\n", + " print i" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "i%2 == 0 " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "l" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "hidden": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "9" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "r" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Untitled2.ipynb b/Untitled2.ipynb new file mode 100644 index 00000000..292dc697 --- /dev/null +++ b/Untitled2.ipynb @@ -0,0 +1,975 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "heading_collapsed": true + }, + "source": [ + "# 1" + ] + }, + { + "cell_type": "code", + "execution_count": 166, + "metadata": { + "hidden": true + }, + "outputs": [], + "source": [ + "# -*- coding: utf-8 -*-\n", + "## Implementation of AVL tree\n", + "#\n", + "# Author: Tim Rijavec\n", + "# tim@coder.si\n", + "# http://coder.si\n", + "\n", + "class avlnode(object):\n", + " \"\"\"\n", + " A node in an avl tree.\n", + " \"\"\"\n", + "\n", + " def __init__(self, key):\n", + " \"Construct.\"\n", + "\n", + " # The node's key\n", + " self.key = key\n", + " # The node's left child\n", + " self.left = None\n", + " # The node's right child\n", + " self.right = None\n", + "\n", + " def __str__(self):\n", + " \"String representation.\"\n", + " return str(self.key)\n", + "\n", + " def __repr__(self):\n", + " \"String representation.\"\n", + " return str(self.key)\n", + "\n", + "class avltree(object):\n", + " \"\"\"\n", + " An avl tree.\n", + " \"\"\"\n", + "\n", + " def __init__(self):\n", + " \"Construct.\"\n", + "\n", + " # Root node of the tree.\n", + " self.node = None\n", + " # Height of the tree.\n", + " self.height = -1\n", + " # Balance factor of the tree.\n", + " self.balance = 0\n", + "\n", + " def insert(self, key):\n", + " \"\"\"\n", + " Insert new key into node\n", + " \"\"\"\n", + " # Create new node\n", + "\n", + "\n", + " # Initial tree\n", + " if not self.node:\n", + " n = avlnode(key)\n", + " self.node = n\n", + " self.node.left = avltree()\n", + " self.node.right = avltree()\n", + " # Insert key to the left subtree\n", + " elif key < self.node.key:\n", + " self.node.left.insert(key)\n", + " # Insert key to the right subtree\n", + " elif key > self.node.key:\n", + " self.node.right.insert(key)\n", + "\n", + " # Rebalance tree if needed\n", + " self.rebalance()\n", + "\n", + " def rebalance(self):\n", + " \"\"\"\n", + " Rebalance tree. After inserting or deleting a node,\n", + " it is necessary to check each of the node's ancestors for consistency with the rules of AVL\n", + " \"\"\"\n", + "\n", + " # Check if we need to rebalance the tree\n", + " # update height\n", + " # balance tree\n", + " self.update_heights(recursive=False)\n", + " self.update_balances(False)\n", + "\n", + " # For each node checked,\n", + " # if the balance factor remains −1, 0, or +1 then no rotations are necessary.\n", + " while self.balance < -1 or self.balance > 1:\n", + " # Left subtree is larger than right subtree\n", + " if self.balance > 1:\n", + "\n", + " # Left Right Case -> rotate y,z to the left\n", + " if self.node.left.balance < 0:\n", + " # x x\n", + " # / \\ / \\\n", + " # y D z D\n", + " # / \\ -> / \\\n", + " # A z y C\n", + " # / \\ / \\\n", + " # B C A B\n", + " self.node.left.rotate_left()\n", + " self.update_heights()\n", + " self.update_balances()\n", + "\n", + " # Left Left Case -> rotate z,x to the right\n", + " # x z\n", + " # / \\ / \\\n", + " # z D y x\n", + " # / \\ -> / \\ / \\\n", + " # y C A B C D\n", + " # / \\\n", + " # A B\n", + " self.rotate_right()\n", + " self.update_heights()\n", + " self.update_balances()\n", + "\n", + " # Right subtree is larger than left subtree\n", + " if self.balance < -1:\n", + "\n", + " # Right Left Case -> rotate x,z to the right\n", + " if self.node.right.balance > 0:\n", + " # y y\n", + " # / \\ / \\\n", + " # A x A z\n", + " # / \\ -> / \\\n", + " # z D B x\n", + " # / \\ / \\\n", + " # B C C D\n", + " self.node.right.rotate_right() # we're in case III\n", + " self.update_heights()\n", + " self.update_balances()\n", + "\n", + " # Right Right Case -> rotate y,x to the left\n", + " # y z\n", + " # / \\ / \\\n", + " # A z y x\n", + " # / \\ -> / \\ / \\\n", + " # B x A B C D\n", + " # / \\\n", + " # C D\n", + " self.rotate_left()\n", + " self.update_heights()\n", + " self.update_balances()\n", + "\n", + " def update_heights(self, recursive=True):\n", + " \"\"\"\n", + " Update tree height\n", + "\n", + " Tree height is max height of either left or right subtrees +1 for root of the tree\n", + " \"\"\"\n", + " if self.node:\n", + " if recursive:\n", + " if self.node.left:\n", + " self.node.left.update_heights()\n", + " if self.node.right:\n", + " self.node.right.update_heights()\n", + "\n", + " self.height = 1 + max(self.node.left.height, self.node.right.height)\n", + " else:\n", + " self.height = -1\n", + "\n", + " def update_balances(self, recursive=True):\n", + " \"\"\"\n", + " Calculate tree balance factor\n", + "\n", + " The balance factor is calculated as follows:\n", + " balance = height(left subtree) - height(right subtree).\n", + " \"\"\"\n", + " if self.node:\n", + " if recursive:\n", + " if self.node.left:\n", + " self.node.left.update_balances()\n", + " if self.node.right:\n", + " self.node.right.update_balances()\n", + "\n", + " self.balance = self.node.left.height - self.node.right.height\n", + " else:\n", + " self.balance = 0\n", + "\n", + "\n", + " def rotate_right(self):\n", + " \"\"\"\n", + " Right rotation\n", + " set self as the right subtree of left subree\n", + " \"\"\"\n", + " new_root = self.node.left.node\n", + " new_left_sub = new_root.right.node\n", + " old_root = self.node\n", + "\n", + " self.node = new_root\n", + " old_root.left.node = new_left_sub\n", + " new_root.right.node = old_root\n", + "\n", + " def rotate_left(self):\n", + " \"\"\"\n", + " Left rotation\n", + " set self as the left subtree of right subree\n", + " \"\"\"\n", + " new_root = self.node.right.node\n", + " new_left_sub = new_root.left.node\n", + " old_root = self.node\n", + "\n", + " self.node = new_root\n", + " old_root.right.node = new_left_sub\n", + " new_root.left.node = old_root\n", + "\n", + " def delete(self, key):\n", + " \"\"\"\n", + " Delete key from the tree\n", + "\n", + " Let node X be the node with the value we need to delete,\n", + " and let node Y be a node in the tree we need to find to take node X's place,\n", + " and let node Z be the actual node we take out of the tree.\n", + "\n", + " Steps to consider when deleting a node in an AVL tree are the following:\n", + "\n", + " * If node X is a leaf or has only one child, skip to step 5. (node Z will be node X)\n", + " * Otherwise, determine node Y by finding the largest node in node X's left sub tree\n", + " (in-order predecessor) or the smallest in its right sub tree (in-order successor).\n", + " * Replace node X with node Y (remember, tree structure doesn't change here, only the values).\n", + " In this step, node X is essentially deleted when its internal values were overwritten with node Y's.\n", + " * Choose node Z to be the old node Y.\n", + " * Attach node Z's subtree to its parent (if it has a subtree). If node Z's parent is null,\n", + " update root. (node Z is currently root)\n", + " * Delete node Z.\n", + " * Retrace the path back up the tree (starting with node Z's parent) to the root,\n", + " adjusting the balance factors as needed.\n", + " \"\"\"\n", + " if self.node != None:\n", + " if self.node.key == key:\n", + " # Key found in leaf node, just erase it\n", + " if not self.node.left.node and not self.node.right.node:\n", + " self.node = None\n", + " # Node has only one subtree (right), replace root with that one\n", + " elif not self.node.left.node:\n", + " self.node = self.node.right.node\n", + " # Node has only one subtree (left), replace root with that one\n", + " elif not self.node.right.node:\n", + " self.node = self.node.left.node\n", + " else:\n", + " # Find successor as smallest node in right subtree or\n", + " # predecessor as largest node in left subtree\n", + " successor = self.node.right.node\n", + " while successor and successor.left.node:\n", + " successor = successor.left.node\n", + "\n", + " if successor:\n", + " self.node.key = successor.key\n", + "\n", + " # Delete successor from the replaced node right subree\n", + " self.node.right.delete(successor.key)\n", + "\n", + " elif key < self.node.key:\n", + " self.node.left.delete(key)\n", + "\n", + " elif key > self.node.key:\n", + " self.node.right.delete(key)\n", + "\n", + " # Rebalance tree\n", + " self.rebalance()\n", + "\n", + " def inorder_traverse(self):\n", + " \"\"\"\n", + " Inorder traversal of the tree\n", + " Left subree + root + Right subtree\n", + " \"\"\"\n", + " result = []\n", + "\n", + " if not self.node:\n", + " return result\n", + "\n", + " result.extend(self.node.left.inorder_traverse())\n", + " result.append(self.node.key)\n", + " result.extend(self.node.right.inorder_traverse())\n", + "\n", + " return result\n", + "\n", + " def display(self, node=None, level=0):\n", + " if not node:\n", + " node = self.node\n", + "\n", + " if node.right.node:\n", + " self.display(node.right.node, level + 1)\n", + " print ('\\t' * level), (' /')\n", + "\n", + " print ('\\t' * level), node\n", + "\n", + " if node.left.node:\n", + " print ('\\t' * level), (' \\\\')\n", + " self.display(node.left.node, level + 1)\n", + "\n", + "\n", + " def find_key(self,key,symbol = \"==\"):\n", + " \"\"\"we are saying node.key symbol(==,>=) key \"\"\"\n", + " if symbol in [\"==\"]:\n", + " if not self.node:\n", + " node_to_return = None\n", + " elif self.node.key == key:\n", + " node_to_return = self.node\n", + " elif self.node.key < key:\n", + " node_to_return = self.node.right.find_key(key,symbol)\n", + " elif self.node.key > key:\n", + " node_to_return = self.node.left.find_key(key,symbol)\n", + "\n", + " return node_to_return\n", + "\n", + "\n", + " if symbol in [\"<=\"]:\n", + " if not self.node:\n", + " node_to_return = None\n", + " elif self.node.key == key:\n", + " node_to_return = self.node\n", + " elif self.node.key < key:\n", + " node_to_return = self.node.right.find_key(key,symbol)\n", + " if not node_to_return:\n", + " node_to_return = self.node\n", + " elif self.node.key > key:\n", + " node_to_return = self.node.left.find_key(key,symbol)\n", + " return node_to_return\n", + "\n", + " if symbol in [\"<\"]:\n", + " if not self.node:\n", + " node_to_return = None\n", + " # elif self.node.key == key:\n", + " # node_to_return = self.node\n", + " elif self.node.key < key:\n", + " node_to_return = self.node.right.find_key(key,symbol)\n", + " if not node_to_return:\n", + " node_to_return = self.node\n", + " elif self.node.key >= key:\n", + " node_to_return = self.node.left.find_key(key,symbol)\n", + "\n", + " return node_to_return\n", + "\n", + "\n", + " if symbol in [\">=\"]:\n", + " if not self.node:\n", + " node_to_return = None\n", + " elif self.node.key == key:\n", + " node_to_return = self.node\n", + " elif self.node.key < key:\n", + " node_to_return = self.node.right.find_key(key,symbol)\n", + " elif self.node.key > key:\n", + " node_to_return = self.node.left.find_key(key,symbol)\n", + " if not node_to_return:\n", + " node_to_return = self.node\n", + " return node_to_return\n", + "\n", + " if symbol in [\">\"]:\n", + " if not self.node:\n", + " node_to_return = None\n", + " # elif self.node.key == key:\n", + " # node_to_return = self.node\n", + " elif self.node.key <= key:\n", + " node_to_return = self.node.right.find_key(key,symbol)\n", + " elif self.node.key > key:\n", + " node_to_return = self.node.left.find_key(key,symbol)\n", + " if not node_to_return:\n", + " node_to_return = self.node\n", + " return node_to_return\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 2" + ] + }, + { + "cell_type": "code", + "execution_count": 188, + "metadata": {}, + "outputs": [], + "source": [ + "tree = avltree()\n", + "data = range(20)\n", + "\n", + "from random import randrange\n", + "for key in data: \n", + " tree.insert(key)\n", + "\n", + "for key in [4,3,68,69]:\n", + " tree.delete(key)\n", + "\n", + "# print tree.inorder_traverse()\n", + "# tree.display()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 189, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]" + ] + }, + "execution_count": 189, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tree.inorder_traverse()" + ] + }, + { + "cell_type": "code", + "execution_count": 190, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(9)" + ] + }, + { + "cell_type": "code", + "execution_count": 191, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9" + ] + }, + "execution_count": 191, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 192, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.delete(7)" + ] + }, + { + "cell_type": "code", + "execution_count": 193, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 1, 2, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]" + ] + }, + "execution_count": 193, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tree.inorder_traverse()" + ] + }, + { + "cell_type": "code", + "execution_count": 194, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(7)" + ] + }, + { + "cell_type": "code", + "execution_count": 195, + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'NoneType' object has no attribute 'key'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mnode_got\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m: 'NoneType' object has no attribute 'key'" + ] + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 196, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 1, 2, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]" + ] + }, + "execution_count": 196, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tree.inorder_traverse()" + ] + }, + { + "cell_type": "code", + "execution_count": 197, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(12,\"<=\")" + ] + }, + { + "cell_type": "code", + "execution_count": 198, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12" + ] + }, + "execution_count": 198, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 199, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(10.1,\"<=\")" + ] + }, + { + "cell_type": "code", + "execution_count": 200, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 200, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 201, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(12,\"<\")" + ] + }, + { + "cell_type": "code", + "execution_count": 202, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "11" + ] + }, + "execution_count": 202, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 203, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(11.2,\"<\")" + ] + }, + { + "cell_type": "code", + "execution_count": 204, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "11" + ] + }, + "execution_count": 204, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 205, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(12,\">=\")" + ] + }, + { + "cell_type": "code", + "execution_count": 206, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12" + ] + }, + "execution_count": 206, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 207, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(10.1,\">=\")" + ] + }, + { + "cell_type": "code", + "execution_count": 208, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "11" + ] + }, + "execution_count": 208, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 209, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(12,\">\")" + ] + }, + { + "cell_type": "code", + "execution_count": 210, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "13" + ] + }, + "execution_count": 210, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 211, + "metadata": {}, + "outputs": [], + "source": [ + "node_got = tree.find_key(10.1,\">\")" + ] + }, + { + "cell_type": "code", + "execution_count": 212, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "11" + ] + }, + "execution_count": 212, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": 213, + "metadata": {}, + "outputs": [], + "source": [ + "tree.delete(11)" + ] + }, + { + "cell_type": "code", + "execution_count": 214, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12" + ] + }, + "execution_count": 214, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "node_got = tree.find_key(10.1,\">\")\n", + "\n", + "node_got.key" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# tree.inorder_traverse()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Untitled3.ipynb b/Untitled3.ipynb new file mode 100644 index 00000000..d32764b6 --- /dev/null +++ b/Untitled3.ipynb @@ -0,0 +1,32 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}