From 7e44f13e2bddda284d4ac2a8453b0ca9e3d13f8d Mon Sep 17 00:00:00 2001 From: kelvin Date: Tue, 14 Nov 2017 16:38:00 +0800 Subject: [PATCH 1/5] Completed bubble sort and merge sort --- sorts/Sorting Algorithms.ipynb | 441 +++++++++++++++++++++++++++++++++ sorts/Sorting_practice.ipynb | 219 ++++++++++++++++ 2 files changed, 660 insertions(+) create mode 100644 sorts/Sorting Algorithms.ipynb create mode 100644 sorts/Sorting_practice.ipynb diff --git a/sorts/Sorting Algorithms.ipynb b/sorts/Sorting Algorithms.ipynb new file mode 100644 index 000000000000..5f46094eda85 --- /dev/null +++ b/sorts/Sorting Algorithms.ipynb @@ -0,0 +1,441 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = 'all'" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "test_x = [9 , 4, 5 ,1 ,3, 8, 6, 7, 4, 0, 5, -4 , -6]" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "13\n", + "i 12\n", + "j 0 i 12\n", + "j 1 i 12\n", + "j 2 i 12\n", + "j 3 i 12\n", + "j 4 i 12\n", + "j 5 i 12\n", + "j 6 i 12\n", + "j 7 i 12\n", + "j 8 i 12\n", + "j 9 i 12\n", + "j 10 i 12\n", + "j 11 i 12\n", + "12 th pass : [4, 5, 1, 3, 8, 6, 7, 4, 0, 5, -4, -6, 9]\n", + "i 11\n", + "j 0 i 11\n", + "j 1 i 11\n", + "j 2 i 11\n", + "j 3 i 11\n", + "j 4 i 11\n", + "j 5 i 11\n", + "j 6 i 11\n", + "j 7 i 11\n", + "j 8 i 11\n", + "j 9 i 11\n", + "j 10 i 11\n", + "11 th pass : [4, 1, 3, 5, 6, 7, 4, 0, 5, -4, -6, 8, 9]\n", + "i 10\n", + "j 0 i 10\n", + "j 1 i 10\n", + "j 2 i 10\n", + "j 3 i 10\n", + "j 4 i 10\n", + "j 5 i 10\n", + "j 6 i 10\n", + "j 7 i 10\n", + "j 8 i 10\n", + "j 9 i 10\n", + "10 th pass : [1, 3, 4, 5, 6, 4, 0, 5, -4, -6, 7, 8, 9]\n", + "i 9\n", + "j 0 i 9\n", + "j 1 i 9\n", + "j 2 i 9\n", + "j 3 i 9\n", + "j 4 i 9\n", + "j 5 i 9\n", + "j 6 i 9\n", + "j 7 i 9\n", + "j 8 i 9\n", + "9 th pass : [1, 3, 4, 5, 4, 0, 5, -4, -6, 6, 7, 8, 9]\n", + "i 8\n", + "j 0 i 8\n", + "j 1 i 8\n", + "j 2 i 8\n", + "j 3 i 8\n", + "j 4 i 8\n", + "j 5 i 8\n", + "j 6 i 8\n", + "j 7 i 8\n", + "8 th pass : [1, 3, 4, 4, 0, 5, -4, -6, 5, 6, 7, 8, 9]\n", + "i 7\n", + "j 0 i 7\n", + "j 1 i 7\n", + "j 2 i 7\n", + "j 3 i 7\n", + "j 4 i 7\n", + "j 5 i 7\n", + "j 6 i 7\n", + "7 th pass : [1, 3, 4, 0, 4, -4, -6, 5, 5, 6, 7, 8, 9]\n", + "i 6\n", + "j 0 i 6\n", + "j 1 i 6\n", + "j 2 i 6\n", + "j 3 i 6\n", + "j 4 i 6\n", + "j 5 i 6\n", + "6 th pass : [1, 3, 0, 4, -4, -6, 4, 5, 5, 6, 7, 8, 9]\n", + "i 5\n", + "j 0 i 5\n", + "j 1 i 5\n", + "j 2 i 5\n", + "j 3 i 5\n", + "j 4 i 5\n", + "5 th pass : [1, 0, 3, -4, -6, 4, 4, 5, 5, 6, 7, 8, 9]\n", + "i 4\n", + "j 0 i 4\n", + "j 1 i 4\n", + "j 2 i 4\n", + "j 3 i 4\n", + "4 th pass : [0, 1, -4, -6, 3, 4, 4, 5, 5, 6, 7, 8, 9]\n", + "i 3\n", + "j 0 i 3\n", + "j 1 i 3\n", + "j 2 i 3\n", + "3 th pass : [0, -4, -6, 1, 3, 4, 4, 5, 5, 6, 7, 8, 9]\n", + "i 2\n", + "j 0 i 2\n", + "j 1 i 2\n", + "2 th pass : [-4, -6, 0, 1, 3, 4, 4, 5, 5, 6, 7, 8, 9]\n", + "i 1\n", + "j 0 i 1\n", + "1 th pass : [-6, -4, 0, 1, 3, 4, 4, 5, 5, 6, 7, 8, 9]\n", + "i 0\n", + "0 th pass : [-6, -4, 0, 1, 3, 4, 4, 5, 5, 6, 7, 8, 9]\n" + ] + }, + { + "data": { + "text/plain": [ + "[-6, -4, 0, 1, 3, 4, 4, 5, 5, 6, 7, 8, 9]" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Implementation #1, bubble up each index\n", + "def bubble_sort(x):\n", + " print(len(x))\n", + " for i in range(len(x)-1,-1,-1):\n", + " print(\"i\",i)\n", + " for j in range(i):\n", + " print(\"j\",j,\"i\",i)\n", + " if x[j] > x[j+1]:\n", + "# temp = x[j+1]\n", + "# x[j+1], x[j] = x[j], x[j+1]\n", + " x[j], x[j+1] = x[j+1], x[j]\n", + "# x[j] = temp\n", + " print(i,\"th pass :\", x)\n", + " \n", + " \n", + " return x\n", + " \n", + "\n", + "# test_x = [8,3,-1,0]\n", + "bubble_sort(test_x.copy())\n" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "13" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-6, -4, 0, 1, 3, 4, 4, 5, 5, 6, 7, 8, 9]\n", + "i:seq[12]:9 , j:seq[0]:-6\n", + "i:seq[12]:9 , j:seq[1]:-4\n", + "i:seq[12]:9 , j:seq[2]:0\n", + "i:seq[12]:9 , j:seq[3]:1\n", + "i:seq[12]:9 , j:seq[4]:3\n", + "i:seq[12]:9 , j:seq[5]:4\n", + "i:seq[12]:9 , j:seq[6]:4\n", + "i:seq[12]:9 , j:seq[7]:5\n", + "i:seq[12]:9 , j:seq[8]:5\n", + "i:seq[12]:9 , j:seq[9]:6\n", + "i:seq[12]:9 , j:seq[10]:7\n", + "i:seq[12]:9 , j:seq[11]:8\n", + "i:seq[11]:8 , j:seq[0]:-6\n", + "i:seq[11]:8 , j:seq[1]:-4\n", + "i:seq[11]:8 , j:seq[2]:0\n", + "i:seq[11]:8 , j:seq[3]:1\n", + "i:seq[11]:8 , j:seq[4]:3\n", + "i:seq[11]:8 , j:seq[5]:4\n", + "i:seq[11]:8 , j:seq[6]:4\n", + "i:seq[11]:8 , j:seq[7]:5\n", + "i:seq[11]:8 , j:seq[8]:5\n", + "i:seq[11]:8 , j:seq[9]:6\n", + "i:seq[11]:8 , j:seq[10]:7\n", + "i:seq[10]:7 , j:seq[0]:-6\n", + "i:seq[10]:7 , j:seq[1]:-4\n", + "i:seq[10]:7 , j:seq[2]:0\n", + "i:seq[10]:7 , j:seq[3]:1\n", + "i:seq[10]:7 , j:seq[4]:3\n", + "i:seq[10]:7 , j:seq[5]:4\n", + "i:seq[10]:7 , j:seq[6]:4\n", + "i:seq[10]:7 , j:seq[7]:5\n", + "i:seq[10]:7 , j:seq[8]:5\n", + "i:seq[10]:7 , j:seq[9]:6\n", + "i:seq[9]:6 , j:seq[0]:-6\n", + "i:seq[9]:6 , j:seq[1]:-4\n", + "i:seq[9]:6 , j:seq[2]:0\n", + "i:seq[9]:6 , j:seq[3]:1\n", + "i:seq[9]:6 , j:seq[4]:3\n", + "i:seq[9]:6 , j:seq[5]:4\n", + "i:seq[9]:6 , j:seq[6]:4\n", + "i:seq[9]:6 , j:seq[7]:5\n", + "i:seq[9]:6 , j:seq[8]:5\n", + "i:seq[8]:5 , j:seq[0]:-6\n", + "i:seq[8]:5 , j:seq[1]:-4\n", + "i:seq[8]:5 , j:seq[2]:0\n", + "i:seq[8]:5 , j:seq[3]:1\n", + "i:seq[8]:5 , j:seq[4]:3\n", + "i:seq[8]:5 , j:seq[5]:4\n", + "i:seq[8]:5 , j:seq[6]:4\n", + "i:seq[8]:5 , j:seq[7]:5\n", + "i:seq[7]:5 , j:seq[0]:-6\n", + "i:seq[7]:5 , j:seq[1]:-4\n", + "i:seq[7]:5 , j:seq[2]:0\n", + "i:seq[7]:5 , j:seq[3]:1\n", + "i:seq[7]:5 , j:seq[4]:3\n", + "i:seq[7]:5 , j:seq[5]:4\n", + "i:seq[7]:5 , j:seq[6]:4\n", + "i:seq[6]:4 , j:seq[0]:-6\n", + "i:seq[6]:4 , j:seq[1]:-4\n", + "i:seq[6]:4 , j:seq[2]:0\n", + "i:seq[6]:4 , j:seq[3]:1\n", + "i:seq[6]:4 , j:seq[4]:3\n", + "i:seq[6]:4 , j:seq[5]:4\n", + "i:seq[5]:4 , j:seq[0]:-6\n", + "i:seq[5]:4 , j:seq[1]:-4\n", + "i:seq[5]:4 , j:seq[2]:0\n", + "i:seq[5]:4 , j:seq[3]:1\n", + "i:seq[5]:4 , j:seq[4]:3\n", + "i:seq[4]:3 , j:seq[0]:-6\n", + "i:seq[4]:3 , j:seq[1]:-4\n", + "i:seq[4]:3 , j:seq[2]:0\n", + "i:seq[4]:3 , j:seq[3]:1\n", + "i:seq[3]:1 , j:seq[0]:-6\n", + "i:seq[3]:1 , j:seq[1]:-4\n", + "i:seq[3]:1 , j:seq[2]:0\n", + "i:seq[2]:0 , j:seq[0]:-6\n", + "i:seq[2]:0 , j:seq[1]:-4\n", + "i:seq[1]:-4 , j:seq[0]:-6\n" + ] + }, + { + "data": { + "text/plain": [ + "[-6, -4, 0, 1, 3, 4, 4, 5, 5, 6, 7, 8, 9]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Implementation 2 : compare with last index directly\n", + "def bubble_sort(seq):\n", + " print(seq)\n", + " for i in range( len(seq)-1, -1 , -1):\n", + "# print(i)\n", + " for j in range(i):\n", + "# print(i,j)\n", + " print(\"i:seq[{}]:{} , j:seq[{}]:{}\".format(i,seq[i],j,seq[j]))\n", + " if seq[j] > seq[i]:\n", + " print(\"{} in index {} swapping with {} in idx {}\".format(seq[i], i, seq[j], j))\n", + " temp = seq[i]\n", + " seq[i] = seq[j]\n", + " seq[j] = temp\n", + " print(\"Swapped Array:\",seq)\n", + " else:\n", + "# print(\"seq[{}]:{} larger than seq[{}]:{}, no swap\".format(i,seq[i],j,seq[j]))\n", + " pass\n", + " return seq\n", + " \n", + " \n", + " \n", + "simple_test = [ 3, -1, 9, 0 ]\n", + "len(test_arr)\n", + "bubble_sort(test_arr.copy())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Merge Sort" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Input arr: [9, 4, 5, 1, 3, 8, 6, 7, 4, 0, 5, -4, -6]\n", + "Input arr: [9, 4, 5, 1, 3, 8]\n", + "Input arr: [9, 4, 5]\n", + "Input arr: [9]\n", + "Input arr: [4, 5]\n", + "Input arr: [4]\n", + "Input arr: [5]\n", + "Input arr: [1, 3, 8]\n", + "Input arr: [1]\n", + "Input arr: [3, 8]\n", + "Input arr: [3]\n", + "Input arr: [8]\n", + "Input arr: [6, 7, 4, 0, 5, -4, -6]\n", + "Input arr: [6, 7, 4]\n", + "Input arr: [6]\n", + "Input arr: [7, 4]\n", + "Input arr: [7]\n", + "Input arr: [4]\n", + "Input arr: [0, 5, -4, -6]\n", + "Input arr: [0, 5]\n", + "Input arr: [0]\n", + "Input arr: [5]\n", + "Input arr: [-4, -6]\n", + "Input arr: [-4]\n", + "Input arr: [-6]\n" + ] + }, + { + "data": { + "text/plain": [ + "[-6, -4, 0, 1, 3, 4, 4, 5, 5, 6, 7, 8, 9]" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "def merge_sort(arr):\n", + "# arr = x.copy()\n", + " print(\"Input arr:\",arr)\n", + " \n", + " if len(arr) > 1:\n", + " midpoint = len(arr) // 2\n", + " left_half = merge_sort(arr[:midpoint])\n", + " right_half = merge_sort(arr[midpoint:])\n", + " \n", + " #Merge\n", + " i = 0\n", + " j = 0\n", + " k = 0\n", + " \n", + " while i < len(left_half) and j < len(right_half):\n", + " if left_half[i] < right_half[j]:\n", + " arr[k] = left_half[i]\n", + " i+=1\n", + " else:\n", + " arr[k] = right_half[j]\n", + " j+=1\n", + " k+=1\n", + " #leftover \n", + " while i < len(left_half):\n", + " arr[k] = left_half[i]\n", + " i +=1\n", + " k+=1\n", + " while j < len(right_half):\n", + " arr[k] = right_half[j]\n", + " j+=1\n", + " k+=1\n", + " \n", + " \n", + " \n", + " return arr\n", + " \n", + " \n", + " \n", + "simple_x = [9,1,8]\n", + "merge_sort(test_x.copy())\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:dlnd-tf-lab]", + "language": "python", + "name": "conda-env-dlnd-tf-lab-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/sorts/Sorting_practice.ipynb b/sorts/Sorting_practice.ipynb new file mode 100644 index 000000000000..1b14aa446edd --- /dev/null +++ b/sorts/Sorting_practice.ipynb @@ -0,0 +1,219 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = 'all'" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "test_x = [15, 6, 1, 7, -3 , 9, 0 , 2, 4, -5 ]" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false, + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "length of x 10 [15, 6, 1, 7, -3, 9, 0, 2, 4, -5]\n", + "Swapped 15 and 6\n", + "Swapped 15 and 1\n", + "Swapped 15 and 7\n", + "Swapped 15 and -3\n", + "Swapped 15 and 9\n", + "Swapped 15 and 0\n", + "Swapped 15 and 2\n", + "Swapped 15 and 4\n", + "Swapped 15 and -5\n", + "i 9 th pass: [6, 1, 7, -3, 9, 0, 2, 4, -5, 15]\n", + "Swapped 6 and 1\n", + "Swapped 7 and -3\n", + "Swapped 9 and 0\n", + "Swapped 9 and 2\n", + "Swapped 9 and 4\n", + "Swapped 9 and -5\n", + "i 8 th pass: [1, 6, -3, 7, 0, 2, 4, -5, 9, 15]\n", + "Swapped 6 and -3\n", + "Swapped 7 and 0\n", + "Swapped 7 and 2\n", + "Swapped 7 and 4\n", + "Swapped 7 and -5\n", + "i 7 th pass: [1, -3, 6, 0, 2, 4, -5, 7, 9, 15]\n", + "Swapped 1 and -3\n", + "Swapped 6 and 0\n", + "Swapped 6 and 2\n", + "Swapped 6 and 4\n", + "Swapped 6 and -5\n", + "i 6 th pass: [-3, 1, 0, 2, 4, -5, 6, 7, 9, 15]\n", + "Swapped 1 and 0\n", + "Swapped 4 and -5\n", + "i 5 th pass: [-3, 0, 1, 2, -5, 4, 6, 7, 9, 15]\n", + "Swapped 2 and -5\n", + "i 4 th pass: [-3, 0, 1, -5, 2, 4, 6, 7, 9, 15]\n", + "Swapped 1 and -5\n", + "i 3 th pass: [-3, 0, -5, 1, 2, 4, 6, 7, 9, 15]\n", + "Swapped 0 and -5\n", + "i 2 th pass: [-3, -5, 0, 1, 2, 4, 6, 7, 9, 15]\n", + "Swapped -3 and -5\n", + "i 1 th pass: [-5, -3, 0, 1, 2, 4, 6, 7, 9, 15]\n", + "i 0 th pass: [-5, -3, 0, 1, 2, 4, 6, 7, 9, 15]\n" + ] + }, + { + "data": { + "text/plain": [ + "[-5, -3, 0, 1, 2, 4, 6, 7, 9, 15]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def bubble_sort(x):\n", + " print(\"length of x\",len(x), x)\n", + " for i in range(len(x)-1, -1 , -1):\n", + " for j in range(i):\n", + " if x[j] > x[j+1]:\n", + " x[j], x[j+1] = x[j+1], x[j]\n", + " print(\"Swapped\", x[j+1], \" and \", x[j])\n", + " print(\"i\",i,\"th pass:\",x)\n", + " return x\n", + " \n", + "bubble_sort(test_x.copy())" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[15, 6, 1, 7, -3, 9, 0, 2, 4, -5]\n", + "[15, 6, 1, 7, -3]\n", + "[15, 6]\n", + "[15]\n", + "[6]\n", + "Merged : [6, 15]\n", + "[1, 7, -3]\n", + "[1]\n", + "[7, -3]\n", + "[7]\n", + "[-3]\n", + "Merged : [-3, 7]\n", + "Merged : [-3, 1, 7]\n", + "Merged : [-3, 1, 6, 7, 15]\n", + "[9, 0, 2, 4, -5]\n", + "[9, 0]\n", + "[9]\n", + "[0]\n", + "Merged : [0, 9]\n", + "[2, 4, -5]\n", + "[2]\n", + "[4, -5]\n", + "[4]\n", + "[-5]\n", + "Merged : [-5, 4]\n", + "Merged : [-5, 2, 4]\n", + "Merged : [-5, 0, 2, 4, 9]\n", + "Merged : [-5, -3, 0, 1, 2, 4, 6, 7, 9, 15]\n" + ] + }, + { + "data": { + "text/plain": [ + "[-5, -3, 0, 1, 2, 4, 6, 7, 9, 15]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def merge_sort(x):\n", + " print(x)\n", + " if len(x) > 1 :\n", + " midpoint = len(x)//2\n", + " left_x = merge_sort(x[:midpoint])\n", + " right_x = merge_sort(x[midpoint:])\n", + " \n", + " #Merge\n", + " i = 0 #left_x current index\n", + " j = 0 # right_x current index\n", + " k = 0 # index of merging parent array, x\n", + " \n", + " while i < len(left_x) and j < len(right_x):\n", + " if left_x[i] < right_x[j]:\n", + " x[k] = left_x[i]\n", + " i+=1\n", + " else:\n", + " x[k] = right_x[j]\n", + " j+=1\n", + " k+=1\n", + " \n", + " #Handle leftovers\n", + " while i < len(left_x):\n", + " x[k] = left_x[i]\n", + " i+=1\n", + " k+=1\n", + " while j < len(right_x):\n", + " x[k] = right_x[j]\n", + " j+=1\n", + " k+=1\n", + " print(\"Merged :\",x)\n", + " \n", + " return x\n", + "\n", + "merge_sort(test_x.copy())" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python [conda env:dlnd-tf-lab]", + "language": "python", + "name": "conda-env-dlnd-tf-lab-py" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From f07b237cad482db59892f17641f6c9acffc0efce Mon Sep 17 00:00:00 2001 From: kelvin Date: Tue, 14 Nov 2017 19:29:11 +0800 Subject: [PATCH 2/5] Added quicksort python implementation --- sorts/Sorting_practice.ipynb | 179 ++++++++++++++++++++++++++++++++++- 1 file changed, 176 insertions(+), 3 deletions(-) diff --git a/sorts/Sorting_practice.ipynb b/sorts/Sorting_practice.ipynb index 1b14aa446edd..93aee34e3168 100644 --- a/sorts/Sorting_practice.ipynb +++ b/sorts/Sorting_practice.ipynb @@ -14,13 +14,14 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 77, "metadata": { "collapsed": true }, "outputs": [], "source": [ - "test_x = [15, 6, 1, 7, -3 , 9, 0 , 2, 4, -5 ]" + "test_x = [15, 6, 1, 7, -3 , 9, 0 , 2, 4, -5 ]\n", + "simple_x = [9, 4 ,2 , 0,- 5]" ] }, { @@ -108,7 +109,7 @@ "cell_type": "code", "execution_count": 17, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [ { @@ -193,6 +194,178 @@ "\n", "merge_sort(test_x.copy())" ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": false, + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Input: [15, 6, 1, 7, -3, 9, 0, 2, 4, -5]\n", + "Pivot: 15\n", + "lesser: [6, 1, 7, -3, 9, 0, 2, 4, -5]\n", + "greater: []\n", + "Merging [6, 1, 7, -3, 9, 0, 2, 4, -5] + [ 15 ] + []\n", + "Input: [6, 1, 7, -3, 9, 0, 2, 4, -5]\n", + "Pivot: 6\n", + "lesser: [1, -3, 0, 2, 4, -5]\n", + "greater: [7, 9]\n", + "Merging [1, -3, 0, 2, 4, -5] + [ 6 ] + [7, 9]\n", + "Input: [1, -3, 0, 2, 4, -5]\n", + "Pivot: 1\n", + "lesser: [-3, 0, -5]\n", + "greater: [2, 4]\n", + "Merging [-3, 0, -5] + [ 1 ] + [2, 4]\n", + "Input: [-3, 0, -5]\n", + "Pivot: -3\n", + "lesser: [-5]\n", + "greater: [0]\n", + "Merging [-5] + [ -3 ] + [0]\n", + "Input: [-5]\n", + "Input: [0]\n", + "Input: [2, 4]\n", + "Pivot: 2\n", + "lesser: []\n", + "greater: [4]\n", + "Merging [] + [ 2 ] + [4]\n", + "Input: []\n", + "Input: [4]\n", + "Input: [7, 9]\n", + "Pivot: 7\n", + "lesser: []\n", + "greater: [9]\n", + "Merging [] + [ 7 ] + [9]\n", + "Input: []\n", + "Input: [9]\n", + "Input: []\n" + ] + }, + { + "data": { + "text/plain": [ + "[-5, -3, 0, 1, 2, 4, 6, 7, 9, 15]" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def quicksort(x):\n", + " print(\"Input:\",x)\n", + " if len(x) <= 1:\n", + " return x\n", + " else:\n", + " \n", + " pivot = x[0]\n", + " print(\"Pivot:\", pivot)\n", + " lesser = [i for i in x[1:] if i <= pivot]\n", + " print(\"lesser:\",lesser)\n", + " greater = [i for i in x[1:] if i > pivot ]\n", + " print(\"greater:\",greater)\n", + " \n", + " \n", + " print(\"Merging \", lesser, \" + [\", pivot , \"] + \", greater)\n", + " return quicksort(lesser) + [pivot] + quicksort(greater)\n", + "\n", + "quicksort(test_x.copy())\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[9, 4, 2, 0, -5]\n", + "in partition lowIndex:0, highIndex:4\n", + "divider first idx:0 pivot idx:4, value:-5\n", + "Swapping pivot x[4] (-5) with divider x[0] (9)\n", + "Swapped pivot with divider: [-5, 4, 2, 0, 9]\n", + "x After partitioning [-5, 4, 2, 0, 9]\n", + "in partition lowIndex:1, highIndex:4\n", + "divider first idx:1 pivot idx:4, value:9\n", + "x[1] (4) is lesser than x[pivot] (9), swapping with divider\n", + "Swapped x: [-5, 4, 2, 0, 9]\n", + "x[2] (2) is lesser than x[pivot] (9), swapping with divider\n", + "Swapped x: [-5, 4, 2, 0, 9]\n", + "x[3] (0) is lesser than x[pivot] (9), swapping with divider\n", + "Swapped x: [-5, 4, 2, 0, 9]\n", + "Swapping pivot x[4] (9) with divider x[4] (9)\n", + "Swapped pivot with divider: [-5, 4, 2, 0, 9]\n", + "x After partitioning [-5, 4, 2, 0, 9]\n", + "in partition lowIndex:1, highIndex:3\n", + "divider first idx:1 pivot idx:3, value:0\n", + "Swapping pivot x[3] (0) with divider x[1] (4)\n", + "Swapped pivot with divider: [-5, 0, 2, 4, 9]\n", + "x After partitioning [-5, 0, 2, 4, 9]\n", + "in partition lowIndex:2, highIndex:3\n", + "divider first idx:2 pivot idx:3, value:4\n", + "x[2] (2) is lesser than x[pivot] (4), swapping with divider\n", + "Swapped x: [-5, 0, 2, 4, 9]\n", + "Swapping pivot x[3] (4) with divider x[3] (4)\n", + "Swapped pivot with divider: [-5, 0, 2, 4, 9]\n", + "x After partitioning [-5, 0, 2, 4, 9]\n" + ] + }, + { + "data": { + "text/plain": [ + "[-5, 0, 2, 4, 9]" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def quicksort(x):\n", + " print(x)\n", + " def quick_sort(x, lowIndex, highIndex):\n", + " if( highIndex - lowIndex > 0):\n", + " p = partition(x, lowIndex, highIndex)\n", + " print(\"x After partitioning\", x)\n", + " quick_sort(x,lowIndex, p-1)\n", + " quick_sort(x,p+1,highIndex)\n", + " \n", + " def partition(x, lowIndex, highIndex):\n", + " \n", + " divider = lowIndex\n", + " pivot = highIndex\n", + " print(\"in partition lowIndex:{}, highIndex:{}\".format(lowIndex,highIndex))\n", + " print(\"divider first idx:{} pivot idx:{}, value:{}\".format(divider, pivot, x[pivot]))\n", + " for i in range(lowIndex,highIndex):\n", + " if x[i] < x[pivot]:\n", + " print(\"x[{}] ({}) is lesser than x[pivot] ({}), swapping with divider\".format(i,x[i],x[pivot]))\n", + " x[i] , x[divider] = x[divider], x[i]\n", + " divider += 1\n", + " print(\"Swapped x:\",x)\n", + " print(\"Swapping pivot x[{}] ({}) with divider x[{}] ({})\".format(pivot,x[pivot], divider, x[divider]))\n", + " x[pivot], x[divider] = x[divider], x[pivot]\n", + " print(\"Swapped pivot with divider:\", x)\n", + " return divider\n", + " \n", + " quick_sort(x, 0, len(x) -1)\n", + " return x\n", + " \n", + " \n", + "\n", + "quicksort(simple_x.copy())" + ] } ], "metadata": { From 7f2e70b8654819717edb214c2ceb61d58ab10e11 Mon Sep 17 00:00:00 2001 From: kelvin Date: Wed, 15 Nov 2017 13:40:55 +0800 Subject: [PATCH 3/5] Added Quicksort algorithms --- sorts/Sorting Algorithms.ipynb | 67 ++++++++++++++ sorts/Sorting_practice.ipynb | 160 +++++++++++++++++++++++++-------- 2 files changed, 191 insertions(+), 36 deletions(-) diff --git a/sorts/Sorting Algorithms.ipynb b/sorts/Sorting Algorithms.ipynb index 5f46094eda85..b9e8b5e5bb86 100644 --- a/sorts/Sorting Algorithms.ipynb +++ b/sorts/Sorting Algorithms.ipynb @@ -415,6 +415,73 @@ "merge_sort(test_x.copy())\n", "\n" ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[9, 4, 5, 1, 3, 8, 6, 7, 4, 0, 5, -4, -6]\n" + ] + }, + { + "data": { + "text/plain": [ + "[-6, -4, 0, 1, 3, 4, 4, 5, 5, 6, 7, 8, 9]" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "## Quicksort\n", + "\n", + "def quick_sort(arr):\n", + " print(arr)\n", + " \n", + " def quickSort(arr, lowIndex, highIndex):\n", + " if highIndex - lowIndex >= 1:\n", + " p = partition(arr, lowIndex, highIndex) # obtained partition index (divider index) is already in its final place\n", + " quickSort(arr,lowIndex,p-1) # Recursive quickSort into portion of the array before and after the partition\n", + " quickSort(arr,p+1,highIndex)\n", + " \n", + " def partition(arr, lowIndex, highIndex):\n", + " divider = lowIndex # initialize divider index\n", + " \n", + " #Custom algorithim to choose pivot, but move it to the highest Index after selecting the pivot\n", + " # Modify pivot position to low or high or random\n", + "# pivot_pos = (highIndex + lowIndex ) // 2 #eg. midpoint for pivot\n", + " pivot_pos = lowIndex #eg. use lowest position as pivot\n", + "# pivot_pos = highIndex # eg. use highest position as pivot\n", + " \n", + " #Swap pivot position to the highest index\n", + " arr[pivot_pos], arr[highIndex] = arr[highIndex], arr[pivot_pos]\n", + " pivot = highIndex # use the highest index as the pivot\n", + " for i in range(lowIndex, highIndex): #loop through all elements, excluding pivot at the highest index\n", + " if arr[i] < arr[pivot]:\n", + " #if element is smaller than the pivot, move it to the begining of the list(behind the divider index)\n", + " arr[divider] , arr[i] = arr[i] ,arr[divider]\n", + " divider+=1 #Increment divider position\n", + " #After completing loop, place the pivot at the divider position. this is its final place.\n", + " arr[divider], arr[pivot] = arr[pivot], arr[divider]\n", + " \n", + " #now return the position of the pivot so we can ignore sorting this position on subsequent recursive calls\n", + " return divider\n", + " \n", + "\n", + " quickSort(arr, 0, len(arr)-1)\n", + " return arr\n", + "\n", + "quick_sort(test_x.copy())\n" + ] } ], "metadata": { diff --git a/sorts/Sorting_practice.ipynb b/sorts/Sorting_practice.ipynb index 93aee34e3168..97270d55f202 100644 --- a/sorts/Sorting_practice.ipynb +++ b/sorts/Sorting_practice.ipynb @@ -281,53 +281,114 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 97, "metadata": { - "collapsed": false + "collapsed": false, + "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[9, 4, 2, 0, -5]\n", - "in partition lowIndex:0, highIndex:4\n", - "divider first idx:0 pivot idx:4, value:-5\n", - "Swapping pivot x[4] (-5) with divider x[0] (9)\n", - "Swapped pivot with divider: [-5, 4, 2, 0, 9]\n", - "x After partitioning [-5, 4, 2, 0, 9]\n", + "[15, 6, 1, 7, -3, 9, 0, 2, 4, -5]\n", + "Current partition snapshot: [-5, 6, 1, 7, -3, 9, 0, 2, 4] + [pivot: 15 ]\n", + "in partition lowIndex:0, highIndex:9\n", + "divider first idx:0 pivot idx:9, value:15\n", + "x[0] (-5) is lesser than x[pivot] (15), swapping with divider\n", + "Swapped x: [-5, 6, 1, 7, -3, 9, 0, 2, 4]\n", + "x[1] (6) is lesser than x[pivot] (15), swapping with divider\n", + "Swapped x: [-5, 6, 1, 7, -3, 9, 0, 2, 4]\n", + "x[2] (1) is lesser than x[pivot] (15), swapping with divider\n", + "Swapped x: [-5, 6, 1, 7, -3, 9, 0, 2, 4]\n", + "x[3] (7) is lesser than x[pivot] (15), swapping with divider\n", + "Swapped x: [-5, 6, 1, 7, -3, 9, 0, 2, 4]\n", + "x[4] (-3) is lesser than x[pivot] (15), swapping with divider\n", + "Swapped x: [-5, 6, 1, 7, -3, 9, 0, 2, 4]\n", + "x[5] (9) is lesser than x[pivot] (15), swapping with divider\n", + "Swapped x: [-5, 6, 1, 7, -3, 9, 0, 2, 4]\n", + "x[6] (0) is lesser than x[pivot] (15), swapping with divider\n", + "Swapped x: [-5, 6, 1, 7, -3, 9, 0, 2, 4]\n", + "x[7] (2) is lesser than x[pivot] (15), swapping with divider\n", + "Swapped x: [-5, 6, 1, 7, -3, 9, 0, 2, 4]\n", + "x[8] (4) is lesser than x[pivot] (15), swapping with divider\n", + "Swapped x: [-5, 6, 1, 7, -3, 9, 0, 2, 4]\n", + "Swapping pivot x[9] (15) with divider x[9] (15)\n", + "Swapped pivot with divider: [-5, 6, 1, 7, -3, 9, 0, 2, 4]\n", + "Full x After partitioning [-5, 6, 1, 7, -3, 9, 0, 2, 4, 15]\n", + "Current partition snapshot: [4, 6, 1, 7, -3, 9, 0, 2] + [pivot: -5 ]\n", + "in partition lowIndex:0, highIndex:8\n", + "divider first idx:0 pivot idx:8, value:-5\n", + "Swapping pivot x[8] (-5) with divider x[0] (4)\n", + "Swapped pivot with divider: [-5, 6, 1, 7, -3, 9, 0, 2]\n", + "Full x After partitioning [-5, 6, 1, 7, -3, 9, 0, 2, 4, 15]\n", + "Current partition snapshot: [4, 1, 7, -3, 9, 0, 2] + [pivot: 6 ]\n", + "in partition lowIndex:1, highIndex:8\n", + "divider first idx:1 pivot idx:8, value:6\n", + "x[1] (4) is lesser than x[pivot] (6), swapping with divider\n", + "Swapped x: [4, 1, 7, -3, 9, 0, 2]\n", + "x[2] (1) is lesser than x[pivot] (6), swapping with divider\n", + "Swapped x: [4, 1, 7, -3, 9, 0, 2]\n", + "x[4] (-3) is lesser than x[pivot] (6), swapping with divider\n", + "Swapped x: [4, 1, -3, 7, 9, 0, 2]\n", + "x[6] (0) is lesser than x[pivot] (6), swapping with divider\n", + "Swapped x: [4, 1, -3, 0, 9, 7, 2]\n", + "x[7] (2) is lesser than x[pivot] (6), swapping with divider\n", + "Swapped x: [4, 1, -3, 0, 2, 7, 9]\n", + "Swapping pivot x[8] (6) with divider x[6] (7)\n", + "Swapped pivot with divider: [4, 1, -3, 0, 2, 6, 9]\n", + "Full x After partitioning [-5, 4, 1, -3, 0, 2, 6, 9, 7, 15]\n", + "Current partition snapshot: [2, 1, -3, 0] + [pivot: 4 ]\n", + "in partition lowIndex:1, highIndex:5\n", + "divider first idx:1 pivot idx:5, value:4\n", + "x[1] (2) is lesser than x[pivot] (4), swapping with divider\n", + "Swapped x: [2, 1, -3, 0]\n", + "x[2] (1) is lesser than x[pivot] (4), swapping with divider\n", + "Swapped x: [2, 1, -3, 0]\n", + "x[3] (-3) is lesser than x[pivot] (4), swapping with divider\n", + "Swapped x: [2, 1, -3, 0]\n", + "x[4] (0) is lesser than x[pivot] (4), swapping with divider\n", + "Swapped x: [2, 1, -3, 0]\n", + "Swapping pivot x[5] (4) with divider x[5] (4)\n", + "Swapped pivot with divider: [2, 1, -3, 0]\n", + "Full x After partitioning [-5, 2, 1, -3, 0, 4, 6, 9, 7, 15]\n", + "Current partition snapshot: [0, 1, -3] + [pivot: 2 ]\n", "in partition lowIndex:1, highIndex:4\n", - "divider first idx:1 pivot idx:4, value:9\n", - "x[1] (4) is lesser than x[pivot] (9), swapping with divider\n", - "Swapped x: [-5, 4, 2, 0, 9]\n", - "x[2] (2) is lesser than x[pivot] (9), swapping with divider\n", - "Swapped x: [-5, 4, 2, 0, 9]\n", - "x[3] (0) is lesser than x[pivot] (9), swapping with divider\n", - "Swapped x: [-5, 4, 2, 0, 9]\n", - "Swapping pivot x[4] (9) with divider x[4] (9)\n", - "Swapped pivot with divider: [-5, 4, 2, 0, 9]\n", - "x After partitioning [-5, 4, 2, 0, 9]\n", + "divider first idx:1 pivot idx:4, value:2\n", + "x[1] (0) is lesser than x[pivot] (2), swapping with divider\n", + "Swapped x: [0, 1, -3]\n", + "x[2] (1) is lesser than x[pivot] (2), swapping with divider\n", + "Swapped x: [0, 1, -3]\n", + "x[3] (-3) is lesser than x[pivot] (2), swapping with divider\n", + "Swapped x: [0, 1, -3]\n", + "Swapping pivot x[4] (2) with divider x[4] (2)\n", + "Swapped pivot with divider: [0, 1, -3]\n", + "Full x After partitioning [-5, 0, 1, -3, 2, 4, 6, 9, 7, 15]\n", + "Current partition snapshot: [-3, 1] + [pivot: 0 ]\n", "in partition lowIndex:1, highIndex:3\n", "divider first idx:1 pivot idx:3, value:0\n", - "Swapping pivot x[3] (0) with divider x[1] (4)\n", - "Swapped pivot with divider: [-5, 0, 2, 4, 9]\n", - "x After partitioning [-5, 0, 2, 4, 9]\n", - "in partition lowIndex:2, highIndex:3\n", - "divider first idx:2 pivot idx:3, value:4\n", - "x[2] (2) is lesser than x[pivot] (4), swapping with divider\n", - "Swapped x: [-5, 0, 2, 4, 9]\n", - "Swapping pivot x[3] (4) with divider x[3] (4)\n", - "Swapped pivot with divider: [-5, 0, 2, 4, 9]\n", - "x After partitioning [-5, 0, 2, 4, 9]\n" + "x[1] (-3) is lesser than x[pivot] (0), swapping with divider\n", + "Swapped x: [-3, 1]\n", + "Swapping pivot x[3] (0) with divider x[2] (1)\n", + "Swapped pivot with divider: [-3, 0]\n", + "Full x After partitioning [-5, -3, 0, 1, 2, 4, 6, 9, 7, 15]\n", + "Current partition snapshot: [7] + [pivot: 9 ]\n", + "in partition lowIndex:7, highIndex:8\n", + "divider first idx:7 pivot idx:8, value:9\n", + "x[7] (7) is lesser than x[pivot] (9), swapping with divider\n", + "Swapped x: [7]\n", + "Swapping pivot x[8] (9) with divider x[8] (9)\n", + "Swapped pivot with divider: [7]\n", + "Full x After partitioning [-5, -3, 0, 1, 2, 4, 6, 7, 9, 15]\n" ] }, { "data": { "text/plain": [ - "[-5, 0, 2, 4, 9]" + "[-5, -3, 0, 1, 2, 4, 6, 7, 9, 15]" ] }, - "execution_count": 79, + "execution_count": 97, "metadata": {}, "output_type": "execute_result" } @@ -336,27 +397,32 @@ "def quicksort(x):\n", " print(x)\n", " def quick_sort(x, lowIndex, highIndex):\n", - " if( highIndex - lowIndex > 0):\n", + " if( highIndex - lowIndex >= 1):\n", " p = partition(x, lowIndex, highIndex)\n", - " print(\"x After partitioning\", x)\n", + " print(\"Full x After partitioning\", x)\n", " quick_sort(x,lowIndex, p-1)\n", " quick_sort(x,p+1,highIndex)\n", " \n", " def partition(x, lowIndex, highIndex):\n", " \n", " divider = lowIndex\n", + " \n", + " # To choose pivot at the position of lowIndex, just swap selected pivot to the last index and isolate it \n", + " # from the modifications\n", + " x[lowIndex], x[highIndex] = x[highIndex], x[lowIndex]\n", " pivot = highIndex\n", + " print(\"Current partition snapshot:\", x[lowIndex:highIndex], \" + [pivot:\",x[pivot],\"]\")\n", " print(\"in partition lowIndex:{}, highIndex:{}\".format(lowIndex,highIndex))\n", " print(\"divider first idx:{} pivot idx:{}, value:{}\".format(divider, pivot, x[pivot]))\n", - " for i in range(lowIndex,highIndex):\n", + " for i in range(lowIndex,highIndex): #Not inclusive of highIndex, pivot ignored in swapping\n", " if x[i] < x[pivot]:\n", " print(\"x[{}] ({}) is lesser than x[pivot] ({}), swapping with divider\".format(i,x[i],x[pivot]))\n", " x[i] , x[divider] = x[divider], x[i]\n", " divider += 1\n", - " print(\"Swapped x:\",x)\n", + " print(\"Swapped x:\",x[lowIndex:highIndex])\n", " print(\"Swapping pivot x[{}] ({}) with divider x[{}] ({})\".format(pivot,x[pivot], divider, x[divider]))\n", " x[pivot], x[divider] = x[divider], x[pivot]\n", - " print(\"Swapped pivot with divider:\", x)\n", + " print(\"Swapped pivot with divider:\", x[lowIndex:highIndex])\n", " return divider\n", " \n", " quick_sort(x, 0, len(x) -1)\n", @@ -364,7 +430,29 @@ " \n", " \n", "\n", - "quicksort(simple_x.copy())" + "quicksort(test_x.copy())" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 2, 3]" + ] + }, + "execution_count": 89, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[ i for i in range(1,4)]" ] } ], From 8f7441ab3019585a480a468dbc7622d8d872919b Mon Sep 17 00:00:00 2001 From: kelvin Date: Sun, 19 Nov 2017 16:25:51 +0800 Subject: [PATCH 4/5] Added confusion matrix --- machine_learning/Confusion_Matrix.xlsx | Bin 0 -> 8945 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 machine_learning/Confusion_Matrix.xlsx diff --git a/machine_learning/Confusion_Matrix.xlsx b/machine_learning/Confusion_Matrix.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..7a1352cf4407097456e97f047e11e8f42fcd1ca8 GIT binary patch literal 8945 zcmeHN1zQ}+)*b=`4-78Bo!~)(4<0lS2ol`g-QC?a1b6qrA-KDHkU($?f$&YT_ulNX z`~8A@>v_6sW~$Da?ymD5d8_56pkXipPXX`%0Du&bNpEgt1_c11!2$pn0Qe{B!d8~{ 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 Date: Sun, 19 Nov 2017 16:45:11 +0800 Subject: [PATCH 5/5] Updated confusion matrix --- machine_learning/Confusion_Matrix.xlsx | Bin 8945 -> 10022 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/machine_learning/Confusion_Matrix.xlsx b/machine_learning/Confusion_Matrix.xlsx index 7a1352cf4407097456e97f047e11e8f42fcd1ca8..0d10528ed6a49d90d751cc1667b1e4dff750c437 100644 GIT binary patch delta 5693 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 delta 4578 zcmZu#WmuG3*B+RmySrzGIJAH?GJt@jgCHT@ohmTEP=X>ol$0PL-6cZ}9n#$?p-77X z$T#1Q@A#hYJ^Q)#b?xW6*Pp%Cz1F(dF4jF&W6;+Ef@lHw073u&zy-(^bn|q@0RSj# z8Mtwg6)70q9#PV$V~sYI)W2Nnz3&lLE?aj|LB-fP!AHzOI`5=emY263Y+)r8urEaq zS*~t7Tb@Dd&28(1Kr>@$Zck#3@r`7QzLwb?kL+FN+B3c|?3N~hECcHnFMheytsuH$ z>x9xO;wP27;_IUBTW!i4FO@!VQZ1aX*|Hc!HX7q}vc(;>_(_Gw1-MBr_?;1^E@WgV zeBD0}1BWW7jZ%bFJ|2qveqW2~Rf=cjuTRMwY{bLbV#clscOx1)Lb?>^=lK~S@NJM^u3_YfDulLo1QND|sPJAYLHI!6*yG5gd=;YI9Ta#aPoEE`4 z{`M9K_-7y*4MlnC+kjj^qGW=ULl8D3O7*+={5Z&pqmJz zOu{qVvqD0>QlzzQ2+V?aj$PrhLtTj;bz&Ob-`QWGmyypae}Fld9qH^eiNhAG;)NzqiU%d|6@>f!njjZ1PWP18oh!<15*Ib-q@#%^8FWiAp5ayOGnpGfG%PbT{DRKq%; zMki*xNmM)bSEHGitm81$mGSWDXc}XkBvVJW623|=%|I#Lj8E!?h1Q8% zP+KlE4tvMfTGb9>qz@2dyWXm&>dsm*fD26 zS~zZI7JOevS4rWCjzfy{xZhCWWa2bXI?$*Md3T)&ZO&2;Ale50In1j9_?Dq8}T z6%mz(mJ{Rt11h0NRnj5y-){?P&#M|a@D5i*0@08~B_i`ob6szJa*=EE&KvLp%RPzQ zVy?@Pn(sKh#g`>8Mm@xbaE65&i4B%^Nb7NU!fK?d^s}7yqsZc32V6FU`TgKu+md5o z^;x-Tf?{vxZ&Wqk?~XC}HfXdA9?bI*jq7z!+ffU@KLEcm&FM#(h{y4!4{=)*^N#eL zao=1b5v)(g``1;|?MEw+HL;!#ClMvW89lii#NF}_Ux|IOYBLNX_%~*$<{sb?W0P+U zyJ-O^B`7`8F6p6Gk0|Ynb-Y`ZK?Aj>M;yJHnOxy|1(BxT*{9G_6Hv*!Y?td2ULej zn_ttj#%(AMBF4fu4hutaW*h6Z#L?jMvTr-7xz&plHBR9&nW8lJ1t!Xlw+k+55+{Xt zI8%ueXX{$E_Nf|V7=w!$N+ON=f*oJlJ$(b8Qvd9CVhk2xn{lUjyoisTc5(`v$wj1K7m-hz|geVe6Q`n~1MpfSbLqu)n)og`t`2vM6l` z$DtBoJGuirmTZNV&>?%_L7IuNpfl4|eJYkbCCheoELUecP-NSD1X0}E-=BV7r76sU zndF&`;(xPs!rk?97?!Gi1i!XNA$((FA$8y!`PPkQ3Wp)118U~I?1Z%xNVXCEOP8i)bT!gY^4cS{G4YciKhq+=W(!FX zkO@TiJ}-M6z5C0wy~{%YOu@}?*`zJjP^twJfpPNI_I#m@R=WSCM!kkcV{X0YT`}{? zx))1Q>+Zl`W6$6dRrz%w(|m(T3+GExu2yz|jck|0-I+QYJ8vqf*{tv%91;^K=(i}T zua7RWmu8SEb?S7%56APx2jgHdN*~lP)+M@&YRkaww4t{%)S@H1D{Nt|x?iF?zGiLG zIVC3>?R0&0kk&pm`K_V#jB;}0+ZzReWmw@4!SxSNa>paGmnUOgI~WEw39ZxStl8+k zU(kfMfSOFiG*Mi;TAL~2^dhj)V(&F4aaCu+vk4ZYls=k2e`eFqS^AJanD~-*>t-=+ zD`{%dbAZ7q;e*IK6EC{xuynofiL9}~m8@}SZTf(9L$1!_yWZ>xEd#gx3Z&PfhjVQ_ z93nzADR&m<%c>_9h}CevF)05ChFqVo>t6!@ttzlj_xvBX>aGzLFKUqvh4h!ZX|!Mz||c}$n-V~ z!FBe={oG3r{!u6mMXHOmF)B3fvaPKTu%Kk+e=kuR9f9f96&w91-d*uSo0NV)0^BSp zUkIkLPYeee-@6IY^Q|f<+H~wLYVlXxndj2-C9EwXqVp6eaW33Ev`(+Z^`zOqqKoq? zu`Q3b_>mHYw=GCdA6Y*FyHY?jIjR(PCGh!iTHht69v?k+l3qq~&Nl!pxh`HO^LP$M zbuFtWC+a5>z7!|JoE?Md*ENzqjw13j#p~=3O#&4|M*+!RpSVyP`V$OrQ;`Wqd_prwSMC2HW&~jYobR&PK*)BmtuI6?Eii0e)V?;AAH5-V|)lPHN)?c=peT_bHmePqM`!=rwfFQp@!KFL{WeX)Qf7d86m9grq zj@FoehLMMgCspbOwoB=$=S&-ZD&I7FD*NL&jEGJPVL z;|dRGtPRtYix{2oxdpN^m6OF!4I zB)F@81|-~Huw&+Ng!1lOhg3IZkYtsIpzXve8<06NmfgiEmw`(gor29`?rRGw298^@ z1+VtBSC={q>)OhO4YRk|Og3!P?|6W{Scc09hDCHfDe9(d4UrjA7%v3-XMK!{^kU&Y0OgVgKcr0rYRxh5w& z7P9{~et${$VSW0C-d?6SPtZ|oKRw|_YcRqYJu7^UQ9qKomfnl<>!>cbBIr+h;P6sa zjQE}pH_|ES>;x3eQM~|d5G{d$9FDj7p9S{5jr?gXN76&w-uS_;& zqRkzSY$w-tzipe~=W#S|jkwH-_a1P=AiTYf-DMcFieF_GzTP~ixvmWi`C1lLtt-!3hVLRE;s~Moj z{&tQeMbE~EgPJ;dQMTj#-AL$=|Raonh&LDX627RpdQ#=v#L@n#O?5K{x~D}E`i^{*$HMiV{XEm8Fx5M!logr`n+uiCWUv;oSz=_B!;a_kqa5C`-$?QS8S|Q`qz6zGIE>6VJX90|A~zg2brwrxhzWBcMQB_BVA>Y zS>+%NtFY0ydr@PJll;t4r`R^X4*aqr>2NxsDXI71*-~6kkpHh&$*ppJ9s67buk)!# z)cA=BrRIbW|2l2C3Ov`O)qu|Q4**i7abx6eF5{MVGB{B{L1}I)i0QkAWNLSk91LCp zP%kq>PGx1c9T}^$Ex4k7HKoiMV3x)KVI_o-ebbR8h~f91oxY8lnGkyT9UQIL%B$%C=zn1d!O%esOB;neJA7uUFGNrEr^{ve1*cp%`8pu6pp z`;~#F->mp|aaTPpmMi%}m?ClBQ@0O|fov);Qj)e`X^`+aCEJjG`cQpMDeW!evG((& z_W6;?uD(WZ!i;YJ9Mi&UEaB4@)oP9II#HQ#x7xnf=dt@2EmClOnTu4I;T>O(*kq8`u{0M^ z5*&UGQQ|w%HaI&g{q~1*IJiPsb^Tv&5GV*3j#G&82eY&MJp^OBE;Ba9f7TGH7A(Z_ z_XG$604V-|*b^D*CzzY{pE~|O4Ui;QRS!jFLzr>Vq^K4Mg!TW6+CSDv8q{3~2kZZ} ze;y(LfbkECJ$cikP8gX{hEU4C{#mB}(+Y^afSsqUzK^GuuZXRuk3H%kl$P~Ru3=wa s{?i-~#)|5Ma