Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kevindavenport/9fcff2613f35ef7d9e62ab2a03d659c1 to your computer and use it in GitHub Desktop.
Save kevindavenport/9fcff2613f35ef7d9e62ab2a03d659c1 to your computer and use it in GitHub Desktop.
Computability, Complexity & Algorithms Part 1
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Computability, Complexity & Algorithms Part 1 from http://kldavenport.com/computability-complexity-algorithms-part-1\n",
"\n",
"## 1. Constant Time O(1)\n",
"Constant time algoritms are described as **O(1)** in big-o notation. These algorithms will always execute at some fixed time regardless of the size of the input.\n",
"Examples:\n",
"- **Looking up a value by key in a dictionary** - Primary keys in dictionaries must be unique. Retrieving the value associated with a key is just a hash lookup, which is a very efficient algorithm to look up items. Python's dictionary is a hash table implementation of collections.abc.Mapping https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping. Methods like xxHash approach working speeds close to RAM limits. To see a great hashing comparison: https://softwareengineering.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed\n",
"- **Finding the middle number of a list** - The length of the list doesn't matter as addtion and division are very optimized compute methods.\n",
"\n",
"More on the complexity of Python operations here: https://wiki.python.org/moin/TimeComplexity"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import matplotlib.pyplot as pyplot\n",
"import numpy as np\n",
"import seaborn as sns\n",
"import random, string, time\n",
"import pandas as pd\n",
"import cProfile \n",
"from pyprof2calltree import convert, visualize\n",
"\n",
"%matplotlib inline"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1.1 Creating our list of dictionaries\n",
"Note these are random but not truly unique keys, a collision could occur. Let's pretend they are unique for the purposes of this demonstration. Below will we create our list of dictionaries that increase in size. These dictionaries will have random string keys and numerical values."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"list_of_dicts = []\n",
"for i in range (1000, 31000, 500):\n",
" rand_dict = {k: random.randint(90000,99999) for k in\\\n",
" [''.join(random.choice(string.ascii_lowercase) for letter in range(5)) for word in range(1,i)]}\n",
" list_of_dicts.append(rand_dict)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Our dictionaries will look like this\n",
"```python \n",
"{'abgri': 90714,\n",
" 'adnju': 94406,\n",
" 'adrki': 96192,\n",
" 'aesht': 90393,\n",
" 'aetfr': 95122,\n",
" 'afrql': 91921,\n",
" 'aifsv': 92711,\n",
" 'aihab': 91017,\n",
" ...\n",
" \n",
" ```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1.2 Searching through each dictionary\n",
"Now we are going to time the simple look up of the string *galqe* across each of our dictionaries."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Dictionary 1 : False | Search Time: 1.9073486328125e-06\n",
"Dictionary 2 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 3 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 4 : False | Search Time: 2.1457672119140625e-06\n",
"Dictionary 5 : False | Search Time: 2.1457672119140625e-06\n",
"Dictionary 6 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 7 : False | Search Time: 4.0531158447265625e-06\n",
"Dictionary 8 : False | Search Time: 1.1920928955078125e-06\n",
"Dictionary 9 : False | Search Time: 2.86102294921875e-06\n",
"Dictionary 10 : False | Search Time: 4.0531158447265625e-06\n",
"Dictionary 11 : True | Search Time: 2.86102294921875e-06\n",
"Dictionary 12 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 13 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 14 : False | Search Time: 2.1457672119140625e-06\n",
"Dictionary 15 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 16 : False | Search Time: 2.1457672119140625e-06\n",
"Dictionary 17 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 18 : False | Search Time: 1.9073486328125e-06\n",
"Dictionary 19 : False | Search Time: 1.9073486328125e-06\n",
"Dictionary 20 : False | Search Time: 2.1457672119140625e-06\n",
"Dictionary 21 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 22 : False | Search Time: 1.9073486328125e-06\n",
"Dictionary 23 : False | Search Time: 2.1457672119140625e-06\n",
"Dictionary 24 : False | Search Time: 1.9073486328125e-06\n",
"Dictionary 25 : False | Search Time: 1.9073486328125e-06\n",
"Dictionary 26 : False | Search Time: 1.1920928955078125e-06\n",
"Dictionary 27 : False | Search Time: 1.1920928955078125e-06\n",
"Dictionary 28 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 29 : False | Search Time: 2.1457672119140625e-06\n",
"Dictionary 30 : False | Search Time: 2.86102294921875e-06\n",
"Dictionary 31 : False | Search Time: 2.1457672119140625e-06\n",
"Dictionary 32 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 33 : False | Search Time: 1.9073486328125e-06\n",
"Dictionary 34 : False | Search Time: 2.1457672119140625e-06\n",
"Dictionary 35 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 36 : False | Search Time: 1.9073486328125e-06\n",
"Dictionary 37 : False | Search Time: 1.9073486328125e-06\n",
"Dictionary 38 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 39 : False | Search Time: 1.9073486328125e-06\n",
"Dictionary 40 : False | Search Time: 1.9073486328125e-06\n",
"Dictionary 41 : False | Search Time: 2.1457672119140625e-06\n",
"Dictionary 42 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 43 : False | Search Time: 2.86102294921875e-06\n",
"Dictionary 44 : False | Search Time: 2.1457672119140625e-06\n",
"Dictionary 45 : False | Search Time: 3.0994415283203125e-06\n",
"Dictionary 46 : False | Search Time: 2.1457672119140625e-06\n",
"Dictionary 47 : False | Search Time: 7.867813110351562e-06\n",
"Dictionary 48 : False | Search Time: 1.9073486328125e-06\n",
"Dictionary 49 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 50 : False | Search Time: 1.1920928955078125e-06\n",
"Dictionary 51 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 52 : False | Search Time: 1.9073486328125e-06\n",
"Dictionary 53 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 54 : False | Search Time: 1.1920928955078125e-06\n",
"Dictionary 55 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 56 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 57 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 58 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 59 : False | Search Time: 9.5367431640625e-07\n",
"Dictionary 60 : False | Search Time: 9.5367431640625e-07\n",
"\n",
"Variance of Search Time across all dictionaries: 0.00000000000120588576\n"
]
}
],
"source": [
"times = []\n",
"for dictionary in enumerate(list_of_dicts):\n",
" \n",
" start = time.time()\n",
" \n",
" if 'galqe' in dictionary[1]:\n",
" state= True\n",
" else:\n",
" state= False\n",
" \n",
" end = time.time()\n",
" times.append(end - start)\n",
" print('Dictionary {} :'.format(dictionary[0]+1), state, ' | Search Time: {}'.format(end - start))\n",
"print(\"\")\n",
"print('Variance of Search Time across all dictionaries:', format(np.var(times), '.20f'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We got a hit on Dictionary 11. We will see some compute time variance as millisecond-level timing is difficult in a real-world OS environment. Our computers are never really \"doing nothing\", it is still switching tasks, doing background jobs, etc.\n",
"\n",
"### 1.3 Plotting the results"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"dict_results_df = pd.DataFrame({'run_time': times, 'dict_size': list(range (1000, 31000, 500))})"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\ny1BWVoZly5bBbDZj69atI6sMERERAQAkEcHQjHfffTfa29sxY8YMJCUladN//etfG7pzY0mv2YfN\nZMFYk2CsSSDWIxhrEow1CZRQlyFKS0ujujNERESUOCIKC77bFomIiGjiiehBUkRERDRxMSwQERGR\nLoYFIiIi0sWwQERERLoYFoiIiEgXwwIRERHpYlggIiIiXQwLREREpIthgYiIiHQxLBAREZEuhgUi\nIiLSxbBAREREuhgWiIiISBfDAhEREeliWCAiIiJdDAtERESki2GBiIiIdDEsEBERkS6GBSIiItLF\nsEBERES6GBaIiIhIF8MCERER6WJYICIiIl0MC0RERKSLYYGIiIh0MSwQERGRLoYFIiIi0sWwQERE\nRLoYFoiIiEiXMtY7QERE8af5TCcOnvgYHV29yJqcgpvzLsV1M6aM9W7RGGFYICKiAM1nOrG3/j3t\n9Sfne7XXDAwTEy9DEBFRgIMnPh7WdBr/GBaIiChAR1dvmOl9Md4TiheGXYZQVRWbNm3CqVOnYLFY\nUFFRgenTp2vzDxw4gO3bt0NRFBQXF2Px4sVh12lvb0d5eTkkScKsWbOwceNGyLKMuro61NTUQFEU\nrF27FgsWLEBfXx9KS0vR2dkJq9WKqqoqZGZm4vjx46iqqoIkSbj++utRWlpq1KETESW0rMkp+OR8\ncGDImpw8BntD8cCwloV9+/bB6XSitrYWDz30ELZs2aLNc7lcqKysxK5du1BdXY3a2lqcPXs27DqV\nlZUoKSnB7t27IYTA/v370dHRgerqatTU1GDnzp3Ytm0bnE4n9uzZg9zcXOzevRt33nknduzYAQDY\nvHkztm3bhrq6Opw4cQInT5406tCJiBLazXmXDms6jX+GtSw0NjZi/vz5AIA5c+agublZm9fW1obs\n7Gykp6cDAAoLC3Hs2DE0NTWFXKelpQXz5s0DABQVFeHQoUOQZRn5+fmwWCywWCzIzs5Ga2srGhsb\nsXr1am1ZX1ioq6uDoihwOByw2+1ITU016tCJiBKarxOj926IPmRNTubdEBOcYWHBbrcjLS1Ne20y\nmeB2u6EoCux2O2w2mzbParXCbreHXUcIAUmStGW7u7t1t+Gb7lsWABRFQVNTE7773e8iJycHn/vc\n53T3PyMjFYpiCjs/K8sWdt5ExZoEY00CsR7B4rUmC7JsWDDvyjH53vFak7ESD/UwLCykpaXB4XBo\n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\nERGRrv8P50TS5uGhnKEAAAAASUVORK5CYII=\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x11f061550>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"sns.set(rc={'figure.figsize':(8,6)})\n",
"sns.regplot(x='dict_size', y='run_time', data=dict_results_df);"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"## 2. Linear time O(N)\n",
"In this class of algorithms the run time scales linearly in response to the input size (N). In the previous O(1) example we saw the fast hash table implementation look-up in Python dictionaries. This implementation was significantly faster than a rote search over a list (even if all elements fit in memory). You can examine the complexity across all python data containers here: https://wiki.python.org/moin/TimeComplexity\n",
"\n",
"Let's use NumPy for a more relevant example of linear time.\n",
"\n",
"numpy.zeros is O(n) as it initializes every element in the array to 0. Even though numpy uses comparatively very fast contiguous c-array when compared to a standard python list, the time complexity is still linear."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.1 Creating our array creation routine functions & removing outliers\n",
"As we've gone over before, there is some practical time inconsistency that we want to smooth out for demonstrative plotting purposes."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"range_spec = list(range(1000, 10001000, 500))\n",
"def arr_create_routines(range_spec, npfunc = np.zeros):\n",
" list_of_times = []\n",
" for i in range_spec:\n",
" start = time.time()\n",
" zero_array = npfunc(i)\n",
" end = time.time()\n",
" list_of_times.append(end - start)\n",
" return list_of_times\n",
"\n",
"def remove_outliers(df_in, col_name):\n",
" q1 = df_in[col_name].quantile(0.25)\n",
" q3 = df_in[col_name].quantile(0.75)\n",
" iqr = q3-q1 #Interquartile range\n",
" fence_low = q1-1.5*iqr\n",
" fence_high = q3+1.5*iqr\n",
" df_out = df_in.loc[(df_in[col_name] > fence_low) & (df_in[col_name] < fence_high)]\n",
" return df_out"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.2. Plotting Results"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"zeros_results_df = pd.DataFrame({'run_time': arr_create_routines(range_spec), 'array_size': range_spec})\n",
"zeros_results_df = remove_outliers(zeros_results_df, 'run_time')"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\nAElFTkSuQmCC\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x122fb1d30>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"sns.set(rc={'figure.figsize':(12,6)})\n",
"sns.regplot(x='array_size', y='run_time', data=zeros_results_df,\n",
" x_bins=20,scatter_kws={\"alpha\":1},line_kws={\"alpha\":0.5});"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This makes me curious if numpy.empty is any faster as it should only be allocating memory, this becomming O(1). Speed differences can be attributed to malloc+memset being slower than calloc in the underlying C implementation: https://stackoverflow.com/questions/27464039/why-the-performance-difference-between-numpy-zeros-and-numpy-zeros-like"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"empty_results_df = pd.DataFrame({'run_time': arr_create_routines(range_spec,npfunc=np.empty), 'array_size': range_spec})\n",
"empty_results_df = remove_outliers(empty_results_df, 'run_time')"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAv0AAAFyCAYAAABmyGWEAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3X14VPWd///XOXMyISQBEkCUVqggaVE3QECEClj41qXb\nsl2RFgg2tlvb7dKVFrbwg6tV1EpBrq78tlbptV4/q2sst4K/y5v9tvvjRlEsCOEbkbRQQaV0K20A\nwUzuJjPn/P5IZjIzmUkmkMnMnDwfvWxy7j/ncDLz/twbjuM4AgAAAOBaZroTAAAAACC1CPoBAAAA\nlyPoBwAAAFyOoB8AAABwOYJ+AAAAwOUI+gEAAACXs9KdADerra1LdxLQTUVF/fXRRw3pTgayAO8K\nksW7gmTxriAZid6ToUMLOz0uZUG/bdt68MEHdeLECXm9Xq1Zs0YjR44Mb9+zZ4+eeOIJWZalefPm\naf78+QmPOX36tFatWiXDMDRmzBg98MADMk1T27Zt05YtW2RZlhYvXqyZM2eqqalJK1as0Pnz55Wf\nn6/169eruLhYFRUV4Wu/9957mjt3rpYvX67HH39cr776qizL0g9/+EOVlpaG93vmmWd07tw5LV++\nPLy8fft2FRcXS5IeeughjRo1KlWPEGlgWZ50JwFZgncFyeJdQbJ4V5CMy31PUhb079q1S36/X1u3\nblV1dbUeeeQR/eIXv5AktbS0aN26dXr++eeVl5en8vJyzZo1S0eOHIl7zLp167R06VLdcsstWr16\ntXbv3q3x48ersrJSO3bsUHNzsxYtWqRbb71VmzdvVklJiZYsWaJXXnlFGzdu1H333afKykpJ0pkz\nZ/T9739fixcvVk1Njd566y1t375dH374oZYsWaIdO3aoqalJP/rRj/TOO+/ob//2b8P3dOzYMa1f\nv1433XRTqh4bAAAA0ONSFvRXVVVp+vTpkqTx48fr2LFj4W2nTp3SiBEjNHDgQEnSxIkTdejQIVVX\nV8c9pqamRpMnT5YkzZgxQ/v375dpmpowYYK8Xq+8Xq9GjBih48ePq6qqSt/61rfC+27cuDEqXT/5\nyU+0YsUK5efnq6qqStOmTZNhGBo+fLiCwaAuXLggj8ejuXPn6tZbb9V7770XPrampkZPPvmkamtr\n9bnPfU7f+c53On0GRUX9ybVnoa6qx4AQ3hUki3cFyeJdQTIu5z1JWdDv8/lUUFAQXvZ4PAoEArIs\nSz6fT4WF7YnNz8+Xz+dLeIzjODIMI7xvXV1dp+cIrQ/tG3L8+HHV19dr6tSp4TQOGjQo6hx1dXUa\nOXKkpk2bpp07d0bd05e+9CUtWrRIBQUFuvfee7V3717NnDkz4TOgXV72GTq0kL4YSArvCpLFu4Jk\n8a4gGYnek64yAikbvaegoED19fXhZdu2ZVlW3G319fUqLCxMeIxpmlH7DhgwIKlzhPYNefHFF/XV\nr341YRpD54jHcRx9/etfV3Fxsbxer2677Tb97ne/6/ZzAQAAAHpbyoL+srIy7du3T5JUXV2tkpKS\n8LbRo0fr9OnTunjxovx+vw4fPqwJEyYkPOaGG27QwYMHJUn79u3TpEmTVFpaqqqqKjU3N6uurk6n\nTp1SSUmJysrK9Nprr4X3nThxYvi6Bw4cCDcfCqXxjTfekG3b+vOf/yzbtsOddGP5fD7NmTNH9fX1\nchxHBw8epG0/AAAAskLKmvfcfvvt2r9/vxYuXCjHcbR27Vq99NJLamho0IIFC7Rq1Srdc889chxH\n8+bN07Bhw+IeI0krV67U/fffrw0bNmjUqFGaPXu2PB6PKioqtGjRIjmOo2XLlik3N1fl5eVauXKl\nysvLlZOTo0cffTScptraWhUVFYWXb7rpJk2aNEkLFiyQbdtavXp1wvspLCzUsmXLdPfdd8vr9Wrq\n1Km67bbbUvX4AAAAgB5jOI7jpDsRbkW7vOxDe0oki3cFyeJdQbJ4V5CMjGvTDwAAACAzEPQDAAAA\nLkfQDwAAALgcQT8AAADgcgT9AIBe8dSRnZrzq3/RL4+8kO6kAECfQ9APAEi5gB3Q9pr/VlPAr201\nv1HADqQ7SQDQpxD0AwBSznYcBeygJClgB2UzWjQA9CqCfgAAAMDlCPoBAAAAlyPoBwC4Eh2HAaAd\nQT8AwHXoOAwA0Qj6AQCuQ8dhAIhG0A8AAAC4HEE/AAAA4HIE/QAAAIDLEfQDAAAALkfQDwAAALgc\nQT8AAADgcgT9AAAAgMsR9AMAAAAuR9APAAAAuBxBPwAAAOByBP0AAACAyxH0AwAAAC5H0A8AAAC4\nHEE/AAAA4HIE/QAAAIDLEfQDAAAALkfQDwAAALgcQT8AAADgcgT9AAAAgMsR9AMAAAAuR9APAAAA\nuBxBPwAAAOByBP0AAACAyxH0AwAAAC5H0A8AMZ46slNzfvUv+uWRF9KdFAAAegRBPwBECNgBba/5\nbzUF/NpW8xsF7EC6kwQAwBUj6AeACLbjKGAHJUkBOyjbcdKcIgAArhxBPwAAAOByBP0AAKBL9HUB\nshtBPwAA6BR9XYDsR9APAAA6RV8XIPsR9AMAAAAuR9APAAAAuBxBPwAAAOByBP0AAACAyxH0AwAA\nAC5nperEtm3rwQcf1IkTJ+T1erVmzRqNHDkyvH3Pnj164oknZFmW5s2bp/nz5yc85vTp01q1apUM\nw9CYMWP0wAMPyDRNbdu2TVu2bJFlWVq8eLFmzpyppqYmrVixQufPn1d+fr7Wr1+v4uJiVVRUhK/9\n3nvvae7cuVq+fLkef/xxvfrqq7IsSz/84Q9VWloa3u+ZZ57RuXPntHz58oRpBgAAADJdykr6d+3a\nJb/fr61bt+oHP/iBHnnkkfC2lpYWrVu3Tr/85S9VWVmprVu36ty5cwmPWbdunZYuXapNmzbJcRzt\n3r1btbW1qqys1JYtW/TUU09pw4YN8vv92rx5s0pKSrRp0ybdcccd2rhxoySpsrJSlZWVWrt2rYYN\nG6bFixerpqZGb731lrZv364NGzbooYcekiQ1NTXpBz/4gTZt2tRlmgEAAIBMl7Kgv6qqStOnT5ck\njR8/XseOHQtvO3XqlEaMGKGBAwfK6/Vq4sSJOnToUMJjampqNHnyZEnSjBkz9Oabb+ro0aOaMGGC\nvF6vCgsLNWLECB0/fjzqHDNmzNBvf/vbqHT95Cc/0YoVK5Sfn6+qqipNmzZNhmFo+PDhCgaDunDh\ngpqbmzV37lz98z//c5dpBgAAADJdypr3+Hw+FRQUhJc9Ho8CgYAsy5LP51NhYWF4W35+vnw+X8Jj\nHMeRYRjhfevq6jo9R2h9aN+Q48ePq76+XlOnTg2ncdCgQVHnqKur08iRIzVt2jTt3Lkz6n7iXa8z\nRUX9ZVme5B4YMsbQoYVd7wTXag74o5aHDClQruWNuy/vSvK681yz8XpdyfZ3JdOep5tl+7uC3nE5\n70nKgv6CggLV19eHl23blmVZcbfV19ersLAw4TGmaUbtO2DAgKTOEdo35MUXX9RXv/rVhGkMnSOZ\n++ls35CPPmrodDsyz9Chhaqtret6R7iWP9gStXzunE9eT06H/XhXuifZ55qt1+uMG96VTHqebuaG\ndyXdnjqyUy/8frfuHPt5fbNsbrqTkxKJ3pOuMgIpa95TVlamffv2SZKqq6tVUlIS3jZ69GidPn1a\nFy9elN/v1+HDhzVhwoSEx9xwww06ePCgJGnfvn2aNGmSSktLVVVVpebmZtXV1enUqVMqKSlRWVmZ\nXnvttfC+EydODF/3wIED4aY/oTS+8cYbsm1bf/7zn2XbtoqLi+PeT6I0AwAAIP0CdkDba/5bTQG/\nttX8RgE7kO4kZZSUlfTffvvt2r9/vxYuXCjHcbR27Vq99NJLamho0IIFC7Rq1Srdc889chxH8+bN\n07Bhw+IeI0krV67U/fffrw0bNmjUqFGaPXu2PB6PKioqtGjRIjmOo2XLlik3N1fl5eVauXKlysvL\nlZOTo0cffTScptraWhUVFYWXb7rpJk2aNEkLFiyQbdtavXp1wvvJycmJm+ZM1xdyvEg93iMAQKaz\nHUcBOyhJCthB2Y6T5hRlFsNxeCKpku4quoAd0Jxf3auAHZRlevTyXY/LMlOWz3MFqlY76mvvkT/Y\noi8+993w8n99bSPNe3pAss81W6/XGTe8K5n0PN3MDe9KOvWV9zTjmvcg/cjxoifwHgEAkP0I+gEA\nAACXI+gHAAAAXI6gHwAAAHA5gn4AAADA5Qj6AQAAAJcj6Acuw1NHdmrOr/5FvzzyQrqTAgAA0CWC\nfqCbmPEPAABkG4J+oJsYtx4AAEjZVfNP0A8AAAB0U7bV/BP0A0AflU0lVECq8feA7sq2mn+CfgDo\ng7KthApIJf4e0BcQ9ANAH5RtJVRAKvH3gL6AoB8AAABwOYJ+AAAA9Cj6SGQegn4AAAD0GPpIZCaC\nfgAAAPQY+khkJoJ+AAAAwOUI+gEAAACXI+gHAAAAXI6gHwAAAHA5gn4AAADA5Qj6AQAAAJcj6Aey\nEJOeAACA7iDoB7IMk54AmYnMOIBMRtAPZBkmPQEyD5lxAJmOoB8AgCtEZhxApiPoBwAAAFyOoB8A\nAABwOYJ+AAAAwOUI+gEAyEKMFpT9+DdEbyLoBwAgyzBaUPbj3xC9jaAfAIAsw2hB2Y9/Q/Q2gn4A\nAADA5Qj6AQAAAJcj6AcAAABcjqAfAADA5RgpCAT9AAAALsZIQZAI+gEAAFyNkYIgEfQDAAAArkfQ\nDwAAALgcQT8AAADgcgT9AAAAgMsR9AMAUqolGNBjBzZFrXvswCa1BBlBBAB6C0E/ACClHn9rs359\n8o2odb8++YYef2tzmlIEAH0PQT8AIGV8/gYdOHM07rYDZ47K52/o5RQBQN9E0A8ASJmzdbU633gx\n7rbzjRf1F9/5Xk4RAPRNBP0AgJS5unCoBucNirttcN4gDSsY3MspAoC+iaA/hS41+fRR48f6uLle\n9f5GNQWa1RIMyHbsdCcNAHpFgbe/plxbGnfblGtLVeDt38spAoC+yUrViW3b1oMPPqgTJ07I6/Vq\nzZo1GjlyZHj7nj179MQTT8iyLM2bN0/z589PeMzp06e1atUqGYahMWPG6IEHHpBpmtq2bZu2bNki\ny7K0ePFizZw5U01NTVqxYoXOnz+v/Px8rV+/XsXFxaqoqAhf+7333tPcuXO1fPlyPf7443r11Vdl\nWZZ++MMfqrS0VBcuXNDy5cvV1NSkq666SuvWrVNeXp6eeeYZbd++XcXFxZKkhx56SKNGjUr4DJqD\nfvkD/rjbDMOUxzTlMUxZpiUzvOyJ+gkA2e7eyeUK2nZUZ94vXD9N904uT8n1Eo0W9P0pdynHk7Kv\nPQDIaCn79Nu1a5f8fr+2bt2q6upqPfLII/rFL34hSWppadG6dev0/PPPKy8vT+Xl5Zo1a5aOHDkS\n95h169Zp6dKluuWWW7R69Wrt3r1b48ePV2VlpXbs2KHm5mYtWrRIt956qzZv3qySkhItWbJEr7zy\nijZu3Kj77rtPlZWVkqQzZ87o+9//vhYvXqyamhq99dZb2r59uz788EMtWbJEO3bs0MaNGzVnzhzd\neeedevLJJ7V161Z94xvf0LFjx7R+/XrddNNNV/x8HMdWIGgrIKlZ8TMGMgx5DFMe0xP10zI9UesA\nIJPleCx9b8qiqKD/e1MWpSwATzRakMc0tWxqRYKjAMDdUhb0V1VVafr06ZKk8ePH69ixY+Ftp06d\n0ogRIzRw4EBJ0sSJE3Xo0CFVV1fHPaampkaTJ0+WJM2YMUP79++XaZqaMGGCvF6vvF6vRowYoePH\nj6uqqkrf+ta3wvtu3LgxKl0/+clPtGLFCuXn56uqqkrTpk2TYRgaPny4gsGgLly4oKqqKn3nO98J\nn2PDhg36xje+oZqaGj355JOqra3V5z73ufA+iQwcmKeAk3OljzKG3fa/FrW0rQlnAtpqCKy233Ni\nWhENGVKgXMvbw+lxn6FDCzvd3hxTe9Pbz7W3r5/u++1t3bnfrt6VTObW96iuuUGH/ueduNsO/c87\n6jfAo8Lcnm9S1NX99fS74tZ/v3RJx/3Fu6aUms+VvvK+9JX7lC7vPUlZ0O/z+VRQUBBe9ng8CgQC\nsixLPp9PhYXtic3Pz5fP50t4jOM4MgwjvG9dXV2n5witD+0bcvz4cdXX12vq1KnhNA4aNCjqHLHn\njjzHl770JS1atEgFBQW69957tXfvXs2cOTPhM7h0qTFh857e4A+2RC3XfHBaeVauPKYnqjlRKJNg\nGjQnGjq0ULW1dZ3uE/tcz53zyevp6cxd5lw/3ffb25K932TelUzm1vfo5PnT+mv9R3G3/bX+I9V8\n8IFGF1/b49ft7P5S8a649d8vXdJxf/Gu+Ymri1PyudJX3pe+cp+JPlO6ygikLOgvKChQfX19eNm2\nbVmWFXdbfX29CgsLEx5jRrRtr6+v14ABA5I6R2jfkBdffFFf/epXE6Yx9hz9+vULn8NxHH39618P\nZwZuu+02/e53v+s06M80LcEWGZ1sj+xnENukiOZEALJBaLSgeMOEMloQgL4sZUW7ZWVl2rdvnySp\nurpaJSUl4W2jR4/W6dOndfHiRfn9fh0+fFgTJkxIeMwNN9yggwcPSpL27dunSZMmqbS0VFVVVWpu\nblZdXZ1OnTqlkpISlZWV6bXXXgvvO3HixPB1Dxw4EG4+FErjG2+8Idu29ec//1m2bau4uDjuOXw+\nn+bMmaP6+no5jqODBw/2SNv+TNLazyCg5oBfDf5G1TXX62LjxzrfcFF/9Z3Xh3W1+tPHf9GHdbX6\na/0FnW+4qItNdaprrldDS5OaA34F7NaaGQBIB0YLAoD4UlbSf/vtt2v//v1auHChHMfR2rVr9dJL\nL6mhoUELFizQqlWrdM8998hxHM2bN0/Dhg2Le4wkrVy5Uvfff782bNigUaNGafbs2fJ4PKqoqNCi\nRYvkOI6WLVum3NxclZeXa+XKlSovL1dOTo4effTRcJpqa2tVVFQUXr7ppps0adIkLViwQLZta/Xq\n1ZKkxYsXa+XKldq2bZuKior06KOPqn///lq2bJnuvvtueb1eTZ06VbfddluqHl/mchwFnaCCdrDT\n3czYWoLw7+0jE9GcCN3x1JGdeuH3u3Xn2M/rm2Vz050cZLDeHi0IALJByoJ+0zT14x//OGrd6NGj\nw7/PmjVLs2bN6vIYSbruuuv03HPPdVg/f/58zZ8/P2pdXl6eHnvssbhpev311zusW7JkiZYsWRK1\nbsiQIXrqqac67HvHHXfojjvuiHtuRLMdW3bQVksn+yRuTsSwpYgWsAPaXvPfCthBbav5je4e//ey\nTPcMvUiGpmf19mhBAJAN+ARE2kQOW5pQgmFLPWZbB2SjtcYg1NEb7mQ7jgJttUsBOyjbRU3I3J6h\nAQBkBr5ZkNmSbU4UZy6D0FCmVttoRUAmcnOGBgCQOQj64Qq2HZStoFqC8RsUmRG1A5GZgRzTYkQi\nAMhANHsDehZBP/qEcB+DeJkCw2jNDBgemf1t+fxN4fkLLNND0yEA6GU0ewN6Hn9BgOMoEAwooEDb\nMKX1UZvbawhaawVsx05wIgBAT6DZG9DzCPqBLgTt1j4FzWqdXTl2Br6zvnPqb/WL23yIvgQAACAT\nEPQDVygQDKhJzXG3GYYp0zCi5i0wDUOetgxBaO4C02DeAgAAkDoE/UAKOY6toCMFO+lkHGJEZABi\nhyWNHKoUAACguwj6gQwRmregU4YRbucaUtdcr/45/aImNgMAAIhE0A9kE8eRHRP0X2qqU2NLU3jZ\naJunIKqPAaMRAQDQpxH0Ay7jOLZaEg1PqtaJzCIzAx7TjFomUwAAgPsQ9AN9jG0H5beDbWMRdRSd\nKTAVZIhSAACyHkE/gCixmYLYIUr//PFflZfTLzwKUaiDceRoRNQYAACQWQj6AXSL7SRuOhTJCGcA\nYjMFntYMQ1vTokwaqrQlGNBjBzZFrXvswCZ9f8pdyvHwcQkASC/HcRS0bQXbJq1z5Mh2bBnquqCN\nbzEAKREajSjQxX5GxNwFiWoNgnbvNDF6/K3N+vXJN6LW/frkG/KYppZNreiVNAAA3MN2bDmOEw7Q\nI3+Pt611vSPHsSP2c1oH8lDrzwbLp4/q6qOuY3ksfVKDO00LQT+AtArPZRAzKlGk2CZG5xouKs/K\njcgomOERii63WZHP36ADZ47G3XbgzFH5JjaowNv/ss4NAMh+rQG6raBjy3ZsNQWie8eda7goy/TI\ndmzZth0O0jMFQT+ArNPU0tRh6NKQ8JClkbUGEZmCRE2KztbV6nzjxbjnPN94UX/xnVdBMUE/AGSj\n9hL11hJ0KVQKrw6l7HZbUG/b7QF+qPQ9UmyBVFNLk7yenF67p+4i6HepFjuoyrdfjlpX+fbLunv8\nl5XDrK5wsfCQpZ3tZBgdZjouyM1Xcb+ButB0qcPug/MGaVhB59WmgFvR1wXpEhmoh4Lz2CYxkU1h\nmoPRJe9nfedkmZZsx86oEvd04a/VpZ47+rJe/+ORqHWv//GITNPUP47/hzSlCsgQjqOgE+zQpOhv\nrh6j1z443GH3cVd/Ws0BvwJ2UGZbH4R8f478wRZ5jNaaA0YrglvR1wVXqinQrIAd7FYb9ssJ1GNL\n3gPBgMwkOrj2FQT9LlTf0qS3PzwRd9vbH55Q/Y1Nys/p18upAjLf10rnyLbtqAzz9BFlKv+bv4ua\n9ViSDF9QH/naO1KFOiSHOiGbbc2IQpmEyMwBGQVkC/q6IFIoaA81eQnadlQb91BzmMZAc9Rx5+o/\nyuhmL30FQb8Lnau/oIvNdXG3XWyu0/mGi8ofeHUvpwrIfDmmRxXj5kQF/RXj5iTVJC7cIVnBzpsW\nRTIMBWJqGy40XlI/KzecMQj1QQgNcQr0Jvq6ZL/QEI+RGlsSl7yH1kW3b+/Ynr0zifpcIb0I+l1o\nSH6xBuUWxg38B+UWanD/QWlIFYAOHKfDl2ODv1GBYOKBTs2YWgRPRA2DGZVRaF8HXK6rC4dqcN6g\nuIE/fV16R2wH1NCyHdnBVO3BeWRpvNMWrMc2eznfQMl7X5R00P/SSy/p5MmT+ud//mf95je/0R13\n3JHKdOEK5Of007hrPh2/bfI1n6ZpD5DFbMeWHezGvAWGIVOGjLZMgNG23GJHZywaW1qr46lRQKQC\nb39NubZUr/xhX4dtU64tdX3THidcAh61tuN+obHUY46JbLceW6Ie2+n0L77zMi4Fda6uru0Ydat0\nHehKUkH/v/3bv+ns2bOqqanRt7/9be3YsUPHjx/XqlWrUp0+XKZEbZO/VjonjakC0OvCE7q0Nj0K\n6bTkL6LfQbz+CWZs/wX6J7javZPLFbTtqM68X7h+mu6dXN6j13HaguZ475LTVsLdYX04II8OtCUp\naNvhEvDI30NNVZyIazbFtEH/08d/kddMbWOI2L/BlmCL/MGWTucsAa5EUm/0G2+8oRdeeEFz585V\nQUGBnn76aX35y18m6M9gV9I2GUAfFxrdqJv9E0KZACOidsEwDBkyFIipWaj3NypoBSUZMiOCvMvJ\nPEQGg6GAryWmiVRLMCBDhgxDCaarb11ntqU5FUIlvVJ7iW/s+lAgGkpD1P8boZQaHQLG2OXupite\nyXTk9n+c8A9RQf83JvyDGgPNagw0d3iaoRLqqBFa2jKfkW3F1Ulpduz9/M/Hf0lpc5QOgTbDO8KF\nkgr6zbaq3tCHkN/vD68DAECOI9sJylb8UsrYIO6jxkspDeJir/cX37nuXa8t49KamTHCGYXWTExE\nxiH0vRiIPz64HEcNlk8XLvku+17iib2/v/rO9+rz/LipjjbhQJZJKuj/whe+oKVLl+rSpUt65pln\n9OKLL2rOHJqJAABcKqJZVDKtqjsbHzxesxQA6G1JBf3/9E//pNdff13Dhw/Xhx9+qCVLlmjmzJmp\nThsAAACAHpB0L5WrrrpKs2bNCi8fOnRIN998c0oSBQAAAKDnJBX0L1u2TL/73e901VVXhdcZhqFn\nn302ZQkDAAAA0DOSCvqPHz+u//qv/5LHw8gvQF/SYgdV+fbLUesq335Zd4//MiNBAQD6rGz8fkxq\nCJ5x48bp9OnTqU4LgAzz3NGXo4Z9laTX/3hEzx19OcERAAC4XzZ+PyZV0j9lyhTNmTNHV111lTwe\nT3gM4d27d6c6fQDSpL6lSW9/eCLutrc/PKH6G5uY3RkAkBF6s+Q9W78fkwr6f/azn+k///M/NXz4\n8FSnB0CGOFd/QReb6+Juu9hcp/MNF5U/8OpeThUAAB0lKnk3TVP/OP4fevRa2fr9mFTQX1RUpEmT\nJjHNOtCHDMkv1qDcwrgfbINyCzW4/6A0pAoAgGi9XfKerd+PSQX9n/nMZzR//nx99rOfVU5O+wx8\n9957b8oS5gZNAb9aAv7WKekNMzyrI5knZIP8nH4ad82n9doHhztsG3fNpzOy6hLJycYOaACQSG+X\nvGfr92NSQf/w4cNp2nMZXj7xmoJ29JT0htE6fXsoE2AaZlSmwDTMtu0RGYXwNkOGIn43zIjjIre1\n/gw60df+sK5WXk9O2/bY63e8NpkVfK10jmzbjqoynT6iTF8rZUbubNab1eAAkGrpKHnPxu/HpIJ+\nSvR7juNIjhzZMQF5KsQG/Yf+XCOPcfmlePEzIu2ZAjN2XdT25DIrkRmQ+JmgjueOn1lpX09m5fLl\nmB5VjJsT9aFWMW4OpcFZLFs7oAFAIukoec/G78dOg/65c+fqhRde0Gc+85mowCk0es/vf//7lCcw\nm40dep2aA37Zji3bceS0/Qwvq/33yJ+O4yTYr31bOrSmKfWZlZ6WfI2KocLzeWps8MfNzIQyK7G1\nNycv/FFejzfheUOZldgMTfwaHzIrSK1s7YAGAJ3JxpL33tZp0P/CCy9Iap2cK5bf709Nilzkxquu\nlz/Q88/JSZBhcGIyCs0Bv17+w77wcZM/cZM8hidin9DxkRmSyPXxMyu2Y7ddP/61O27PnsxKg9Og\nxsaWTs5l6+2z0aWkW975tcZd/WmZRlLTXiQtukajPXNgO3bUfm/88f+0NdvqqnlYolqX+M3DQtti\nMzl1zQ1QDxa3AAAgAElEQVTqZ3kT1riQWcls2doBDQA6k40l770tqeY9CxYs0NatW8PLtm1r3rx5\neumll1KWMCRmRJQSd8YfjA5ery4YIq8nJ8HeqRebWek8oxA/09FZZqOzzEq8c8fWqNiOrTxvjuwW\nI2Fm5ehf/qA/fnw26r7++PFZGYah8Vd/pkefl+04kuMoqOggP7bZ1oXGS1fUbKsrsdfb+8FbnV4v\nXmalq1qNjjUj0ZmV2IzHex/9Kdw/JVE/lGSbnvW1zEq2dkADAFyZToP+u+++W2+99ZYkaezYsZJa\nAzfLsjRr1qzUpw6ukmxmJZ2KivP10YX6qHWhzEqdv1Gvvn8o7nEfNX6smz9xk/pZ3oiMSPxmXB2b\nb7XXsrRuT1zrYju2WoKBqGvn5+TJMIy4tTLpkCizciViMx7H/nqyxzM6ocyAE/Pc9rz/lnJMq0NG\noeBCPzXW++NkJLrXKT8YU3NzruGiciOaiyXq7xL6W7qczArV4ADQ93Qa9D/77LOSpDVr1ui+++6L\nu09NTY1uvPHGnk8ZkCFCmZWLjZd0ye+Lu8/H/nrZjq0hvdA0wh9sUWXENN//a9QtcWtwOqtZ6azG\nJVQzErTttmZiLVHNxMYOuU4e0xOn5iR+ZiVxH5XI7RmUWYnJYPj8DXEzGD47p9OmYMmKvd6bZ6q7\nlaFpz3CEMhpdZxRMw9BnhlwXFfSPu7pEv689ddmd8jurzTENQwE7+/oDoW9gCFv0FUk170kU8Ie2\nhdr+A26WbW2he6pmJbaZ2JjBI1PaTKw9s9KeKWiK6Z9y28hJskxPdOahi34uiWtWorf5Y2pSivoN\nkGmYHc7fLydHQb8TzsgE7Z6r2eiO9poVSUo+sI7NbHxw8c+92kzs5T+8Jsu04mRWopt2xetw37E2\nJTqTYhpmh0zGmUtnw31fEmVWkmke1leagfUlDGGLviKpoL8zsVXhgFvRFrp3tGdWJMkTXhdpYL+C\nlGU8/MEW/T9HdoaXp48si3ut2KZg8TIrXdWsxOtwP27YpxNkaBLXkESfv7NO+e21OS3pyaOE2U5r\nRqm7mZVkxWYy/s/Z4z2SqTEMxc10xOtgn2NaMg1ThR/1U0N9vFHBOh+uOP4IYvEzNXXN9cq1vAn7\nyZBZiY8hbNGXXHHQzwcJ+hLaQiOReJmVZMTWpIwcdE2vdLj3B1v0/x7fG17+4pjpyjGthJmN+JmM\n+B3i4zXjir3PTxQOk8c0u51ZiU5Tyh9TB44jBZ2OmZXOOtjX9VBTsEgdO9gf6jRTE5lZic10JBrF\nKzIjEpupqfnrSXk93i6HIo7t75KoZiX2uN5qDsYQtuhLrjjoB/oShgSDW1mmRzme1H0lxAb9E4eP\nveLMTaJMR7walM9eOz6qBiXevCmhfixd9XeJN0pYi92xg30oWM61chTw2BmUWem+2EzGqY/+1KvN\nwf73u2/IMj0xmZWuhiLuumalORhQQU5/+VoaOqShMKe/AnZQf62/0Ols9YmahwGZhqAfAJCVTMOU\njPj1KrEZiiH9B6W0BsUfbNGzb7cPYx3ZwT62KVhsZqWrIYWjazda92kO+mM62I+SxzQT1LzEq7VJ\ntnlY2/o09VkJabEDSlUn/8H9B8p3qWPQX9x/YId5WZIVqlmJnVG+s9qTg396R4PqCtRY3xwzb0rX\ns9XHbx7Wvk9szUlDS5OCth23xoUWHO6Vsjb9tm3rwQcf1IkTJ+T1erVmzRqNHDkyvH3Pnj164okn\nZFmW5s2bp/nz5yc85vTp01q1apUMw9CYMWP0wAMPyDRNbdu2TVu2bJFlWVq8eLFmzpyppqYmrVix\nQufPn1d+fr7Wr1+v4uJiVVRUhK/93nvvae7cuVq+fLkef/xxvfrqq7IsSz/84Q9VWlqqCxcuaPny\n5WpqatJVV12ldevWKS8vL26aAQDojs4yK8nq2MF+RMozNS+eeC28/IXrb22rOelq7pXuzbdih2tO\nou/vmoKhMtuGJu6sxqVDZsVxuswslA4rkeM4UXOwjBhwtUqHlVz28wrVrHQmtjbjL/XnVe/U93hT\nsHjX2vXegbg1NYahBCNxJT8UsSOnw/DWPz+4WbOvv1U54dqarkYY63peFzIr3Zd00P/uu+/q0qVL\nUUH+zTffrJ///Odx99+1a5f8fr+2bt2q6upqPfLII/rFL34hSWppadG6dev0/PPPKy8vT+Xl5Zo1\na5aOHDkS95h169Zp6dKluuWWW7R69Wrt3r1b48ePV2VlpXbs2KHm5mYtWrRIt956qzZv3qySkhIt\nWbJEr7zyijZu3Kj77rtPlZWVkqQzZ87o+9//vhYvXqyamhq99dZb2r59uz788EMtWbJEO3bs0MaN\nGzVnzhzdeeedevLJJ7V161bdddddcdM8ZMiQK3n+AABkHa8nJ+WZjEg3f+LGy76ekyCjEFnrMX1k\nmf6v/+//Dh/z7Ynz5DE9CTMrXQ1FHNon2EmtTeycK15PjnI8OfKbwbTNYu84akvj5fepqD57XKcv\nfRi17p2/vquPm309PollJNMw5Cj6me1+76ByPFaXQwonGoq4qxHEYkdtO9fwkXLDfV26rpXp7cxK\nUkH/Qw89pL179+raa68NrzMMQ88++2zUukhVVVWaPn26JGn8+PE6duxYeNupU6c0YsQIDRw4UJI0\nceJEHTp0SNXV1XGPqamp0eTJkyVJM2bM0P79+2WapiZMmCCv1yuv16sRI0bo+PHjqqqq0re+9a3w\nvhs3boxK109+8hOtWLFC+fn5qqqq0rRp02QYhoYPH65gMKgLFy6oqqpK3/nOd8Ln2LBhg6ZMmRI3\nzX/3d3+XzCMEAABpYBhGl/0PYjMZwwoGp7xDvT/Yos3H/nd4+QvX36phQweFm4IlyqzEH4q483lT\nYudbKRk8skNNTaJ5U7qeYLI9o9McbNFZ3/m493vWd14tdkA5ZmpalttOx3lW6lsa5Qn0Xt+TN8+8\n3e2+Lpczo3zhR3lqbPBHZVYsT47+5rrrOr1WUk9+//79+vWvf61+/ZIftsrn86mgoCC87PF4FAgE\nZFmWfD6fCgsLw9vy8/Pl8/kSHuM4TjgnlJ+fr7q6uk7PEVof2jfk+PHjqq+v19SpU8NpHDRoUNQ5\nYs/d1fU6M3BgngJO6kfhSMQfiP4QKyrKl9dKX3qyRVFxfqfb0/1ce/v66b7f3k5Dd67V1bvS09fr\nSW5/jzLtej3xrnTnej2N6/XONaWef1fC13qjfXnqmJtScn+nzv9Jr0RkLiI1B/367PV/o2sHDYuq\nEbHttt/lyLZtxdaYRGZ0ompOQvuGj3Na7/MP7de8dvBVMk0jnAGKrYUJX7ttXXcF7egAP6+fVx7z\nSjpxO1JrA7WOc9o7bf9J+vhSxxGnzCSum1TQf+2113b7YRQUFKi+PqLjkm3Lsqy42+rr61VYWJjw\nmMgbqa+v14ABA5I6R2jfkBdffFFf/epXE6Yx9hz9+vXr8nqduXSpUf6Av+uHlSKxJRcffVTfK0MB\nZrPYDnfxpPu59vb1032/vZ2GZK+VzLvSk9fraW5/jzLpej31riR7vVTger1zzciS/lRfKxX3lxvI\n63QSyyKzSE6jKUOSR57E/VqMtv+6KfY+Jwy5Ien77GwW+86GIt6uXeFzfGbQqLYZ65MZijiZuVji\nXzu3n6WGhubwstSDQf/AgQP1pS99KdycJmTdunUJjykrK9PevXv1xS9+UdXV1Sopae8QM3r0aJ0+\nfVoXL15U//79dfjwYd1zzz0yDCPuMTfccIMOHjyoW265Rfv27dOUKVNUWlqqf//3f1dzc7P8fr9O\nnTqlkpISlZWV6bXXXlNpaan27duniRMnhq974MABffvb345K409/+lPdc889Onv2rGzbVnFxcfgc\nd955Z/gcidIMAACA7J7E8nJmsY/NZFw78OpeKbSJLEgIZVbMJIYOTyronz59eritfbJuv/127d+/\nXwsXLpTjOFq7dq1eeuklNTQ0aMGCBVq1apXuueceOY6jefPmadiwYXGPkaSVK1fq/vvv14YNGzRq\n1CjNnj1bHo9HFRUVWrRokRzH0bJly5Sbm6vy8nKtXLlS5eXlysnJ0aOPPhpOU21trYqKisLLN910\nkyZNmqQFCxbItm2tXr1akrR48WKtXLlS27ZtU1FRkR599FHl5OTETTMAAABaMYll7wplVqyeCvpv\nueWWbifCNE39+Mc/jlo3evTo8O+zZs3SrFmzujxGkq677jo999xzHdbPnz+/w7CZeXl5euyxx+Km\n6fXXX++wbsmSJVqyZEnUuiFDhuipp57qsG+8NAMAAKAVk1hmrqSC/q997WsyDEOO4ygQCOjcuXMa\nO3asduzYker0AQAAALhCSQX9e/bsiVo+evSofvWrX6UkQQAAZJMWO6jKt1+OWlf59su6e/yXKd0E\nkDEua1yh0tJS1dTU9HRaAADIOs8dfTmqKYMkvf7HI3ru6MsJjgCA3pdUSf/jjz8etXzy5EkNHjw4\nJQkCACBb1Lc06e0PT8Td9vaHJ1R/Y5OK1PPjrgNAdyVV0v+nP/0pavnmm2/Wz372s5QkCACAbHGu\n/kLcMckl6WJznc43XOzlFAFAfEmV9L/77ru67777ombLBQCgrxuSX9zpZESD+w+KcxQA9L6kgn7T\nNDVr1ixdd911ys3NDa9/9tlnU5YwAAAyXTZPRgSgb0kq6F+xYkWq0wEgCYwSAmSe3p6MiM8BAJcj\nqaB/8uTJqU4HgCQkGiXENE394/h/SFOqkHaGIUkyZUiGIbNthsbWmRpbOWqfrt12HJl28LKvFTqr\n0cWukWKniO9n5SrX8so0zPA8MK3pdNrSKaktvZGilzpPZ6QcT45yPDkRm1vvwmh7ZkbbOsdxop5T\nKE2247Slp3VZTntKensyIj4HAFyOpIJ+AOmXzCghNCXoJUZbQG20joVgRKyPXDbCy0bEodHBpuWJ\n/hguzC1Qv7Zg2Gy7jmmYMtQazEuGDKP9nIbRndC7nT/YErV8TeFQ5XiscKBrO7bMtvtrzUS0p6cn\nrjckv0jeiCC8p8Veb1jB4B6/Xihz4DiOGgPNUdsKcvPlMUzZjq0cjyXDMOU49hVfk88BAJeLoB/I\nEsmMEpI/8OpeTlXPMgyzNZSNKHkNBceR8nL6KdfyRpVmh44NBaVm6FxtQbIZDtBDwXLEdSOCcn8w\nEHWtTwwYJq8np0OwO7SoUP0D8f89uiM2OB3YryClwXAiHtMjy+QroTva3091+Dcb1K8wvG7owEJ5\n/XlyHEdBJyjbcRS0bSmiHiOypkMd1oV+d1TbBz4HAKQGn/BAlsiUUUI8pkeWx0pcet26IioAD603\nDVMe05THMNtKss2oEu1EYgPjwf0HpSww9sSUxhpXULoNRDIMQ5bR9rV7mS1/xgz5lAbnDdL5xo5D\ngRb3G6ixQ0epf04/BR1btmMraAdbf7dtBR277ffLbNqFHpOoX8bSWeVpShH6AoJ+IEt0NkrIxOE3\naEj/QeH20aGSbzMi6G5v322ES7kNGeGSxfYmyq1rDLUG6YGYAOGawqFpKYkGIBV4+2vKtaV65Q/7\nOmybOmKcivIGJHWeoG0r6AQVtNsyB7GZBMdW0LZ7pEkSOkrUL6P/b3NVPvaLaUoV3I6gH8hgrSXj\nnramFx79y80LlWPmaNd7vw3v84Xrp+n7U+5Sjic1f85GTCk7gPS6d3K5gratX598I7zuC9dP072T\nky8l9pimPDK7rHEINUlqCvij1hfm5kd1jHYiOjbbbZkG23HCGYjIjs99XWf9Mg79sUZfvn4W/TKQ\nEgT9QG8xjHCzFk9bibwZ8TM04kqoCYxlesLt0CP962crooL+701ZlLKAH0DmyfFY+t6URVFBf6o+\nB0JNkrye6KB9YESfhWTYjh3R8bl1XWz/hVBGwXZsNcV0jLY8lsy2jtHZrrP+WRcaP+7xfhkM8YoQ\nIgXgSrWNwOIJlcqHf3rkMVuDeY/hoV04gD7LNMxujfGaa3mjlq8uGBLOZISaJrVnJBTODNgRQ66G\nmiqFfmZKbUNn/bOK8wb0eP8shnhFCEE/0MYwWkvXc9pGajFlyDTNqNJ30zDVEjO6yyfbRncBAKRe\nuGlSN8VmAuxw7YIto6X3CmU6659184gbe7RpD0O8IhJBP9ytremMJ/Sf6WkteW8rkW8fTaa1JH7o\noELltnQ+DKPfpI07AGQbj+mRRx4pTiGN39s/anlYwRB5zNaBDGIzCz3RwTnRLM7/NPVO1V1suqJz\nR+oLQz0jeQT9yEpGzNCPnrb2756IEvlQ8xoAALojx2N1WoMb6uAcOfpR7EhInY2AlGgWZ6uH29hn\nylDPyAwE/Ug70zAjmtEY4aEmQ7OQhoL7cCk97eMBAGkU6uBsJVmuFLRtOYpsUuR06Kzcz8pVruWV\nx2xq65tw5Z2WO2tKNO6aT9O0p48h6EdKGW2j00Q2r7Ha/gv9Hm+EGgAA3KK11jn6uy62VH9IfpGu\nGVAsqzlXUvuIRpG1CLZjh5scBZxg6zwqXXRQTtSU6Gulc3rm5pA1CPoRJVTqHjVTalsJfOTwkqFJ\nniTJMNonf2o9hyFDJk1r0CNaggE9dmBT1LrHDmxK6dwEAJBuRlvNdms/hMT7Be3W4D/U7yDcxKht\nFmbT9Khi/N93aErEcJ19D9+YbhMxFrwZ8wc9oF+h+rUNgxYK0s2Ijq6hoB7IJI+/tTlqPHJJ+vXJ\nN+QxTS2bWpGmVKG7TMOQZXoUsINtNXx81gA9ITSBY2f8MZMsDsobII/hiZqFmYnU3I+gP9U6TLzU\n3ma926cKB+rREzmFA/e2EvqQ2D/yAbn5DC2JrOLzN+jAmaNxtx04c1S+iQ0qiBl1A5nJMi3Nv3G2\ndv5+l+4c+3lZJl8/QLoUePsnjAfaOyQH2zos221NjVqbGzlyooY7tdv2R+bjUzeFrsovTncSgKx2\ntq5W5xsvxt12vvGi/uI7r4Jigv5s8c2yufpm2dx0JwNAJ0LzIOR0M0QMZRYcOWpsie6knO/tL4/p\nkdPWiZlahfQg6AeQsa4uHKrBeYPiBv6D8wZpWMHgNKQKABCrs0nTivIGxK1ZCNcWOE5UZ2U7JnOQ\nabMqZyuCfgAZq8DbX1OuLdUrf9jXYduUa0uzvmkPnZQB9GWhQUMkddpZOSRo223zI8ROmNb6s8UO\npjbBWY5vFQAZ7d7J5QradlRn3i9cP033Ti5PY6p6Bp2UASB54dqEBP0RYvsyDuxXKNMwFbAD4aFO\n+zKCfgAZLcdj6XtTFkUFx9+bsijrS8LppAwAqVUYM4CJ4zgK2EEF7IBaQj+DAbXYgT7RdCi7vzUB\nIEvRSRkAepdhGMrxWMrxWMqL2daaAQhlCFozAwE72CMzI2cKgn4ASAM6KQNA5rBMq20o4dyo9UE7\nqJa25kEBO6hAMNA+G3KWIegHgDRweydlAHCDziY/a2xpilouzM2XZVoZO+oQQT8ApImbOykDgNvF\nZgYG9iuMOzRpMFRLEDHaUKhfgd2LNQYE/QCQJm7tpJwJTMOQZXoUsIOyTM9lzYIOAD0hVFuQG2eb\n4zhqsQNtzYiCUSMN9XQtAd8sAADXsUxL82+crZ2/36U7x36+ra0uAGQWwzBaawc8OR06F0uRcxO0\nz1FQkNtfDVaLgo7d2rcgyYwBn4IAAFf6ZtlcfbNsbrqTAQCXrX1ugvZ1Q/IL5TS0rwjNZtwVgn4A\nAAAgS4UzBl3oeg8AAAAAWY2gHwAAAHA5gn4AAJAxWoIBPXZgU9S6xw5sUkswkKYUAe5A0O9ioSHr\nJDFkHQAgKzz+1uaoYWwl6dcn39Djb21OU4oAdyDod7HQkHX9LK/m3zibIesAABnN52/QgTNH4247\ncOaofP6GXk4R4B5EgS7HkHUAgGxxtq5W5xsvxt12vvGi/uI7r4Li/r2cKsAdKOkHAAAZ4erCoRqc\nNyjutsF5gzSsYHAvpwhwD4J+AACQEQq8/TXl2tK426ZcW6oCL6X8wOUi6AcAABnj3snl+sL106LW\nfeH6abp3cnmaUgS4A0E/AADIGDkeS9+bsihq3femLFKOh26IwJUg6AcAAABcjqAfAAAA6KZsmw8p\nZXVltm3rwQcf1IkTJ+T1erVmzRqNHDkyvH3Pnj164oknZFmW5s2bp/nz5yc85vTp01q1apUMw9CY\nMWP0wAMPyDRNbdu2TVu2bJFlWVq8eLFmzpyppqYmrVixQufPn1d+fr7Wr1+v4uJinT59Wg888IBa\nWlrk9Xq1YcMGFRUVac2aNTpy5Ijy8/O1fPlyjRs3TmfOnNGqVavkOI6GDx+uhx9+WHl5eXrmmWe0\nfft2FRcXS5IeeughjRo1KlWPEEAahD7EA3YwKz7EAQDpEZoPaefvd+nOsZ/P+PmQUpa6Xbt2ye/3\na+vWraqurtYjjzyiX/ziF5KklpYWrVu3Ts8//7zy8vJUXl6uWbNm6ciRI3GPWbdunZYuXapbbrlF\nq1ev1u7duzV+/HhVVlZqx44dam5u1qJFi3Trrbdq8+bNKikp0ZIlS/TKK69o48aNuu+++3T//ffr\nX//1XzV+/Hj95je/0QcffKDq6mq9//77ev7553Xx4kV961vf0s6dO/XTn/5UCxcu1N///d9r+/bt\nevrpp/Xd735Xx44d0/r163XTTTel6rEBSLNs+xAHAKRPNs2HlLLmPVVVVZo+fbokafz48Tp27Fh4\n26lTpzRixAgNHDhQXq9XEydO1KFDhxIeU1NTo8mTJ0uSZsyYoTfffFNHjx7VhAkT5PV6VVhYqBEj\nRuj48eNR55gxY4Z++9vfqqmpSRcuXNDevXtVUVGh6upqlZaW6uTJk5o+fbpM01RxcbE8Ho9qa2t1\n8uRJzZgxQ5JUVlamqqqqcDqefPJJlZeX6z/+4z9S9egApNk3y+bq5bueyJoPcgAAupKyIiyfz6eC\ngoLwssfjUSAQkGVZ8vl8KiwsDG/Lz8+Xz+dLeIzjODLaqtjz8/NVV1fX6TlC60P7Xrp0Se+++67u\nu+8+LV26VD/60Y/0wgsvaOzYsXr66ad111136ezZszp58qQaGxs1duxY7dmzR3PnztXu3bvV2Ngo\nSfrSl76kRYsWqaCgQPfee6/27t2rmTNnJnwGRUX9ZVmennmg6DVDhxZ2ur054I9aHjKkQLmWN5VJ\nSuv1032/mZKGeLp6V5KRrnvL1Gearbp6nj3xrnTnej2N6/XONaWef1cSXcttzzOd102Hy3lPUhb0\nFxQUqL6+Prxs27Ysy4q7rb6+XoWFhQmPMU0zat8BAwYkdY7QvgMHDlR+fr6mTJkiSZo5c6b279+v\nr3zlK3rnnXdUUVGhMWPG6MYbb9SgQYO0cuVKPfzww9q5c6dmzJihoqIiOY6jr3/96+EMxW233abf\n/e53nQb9H33UcCWPEGkwdGihamvrOt3HH2yJWj53zievJyeVyUrr9dN9v5mShljJvCvJSNe9ZeIz\nzWadPc+eeleSvV4qcL3eueYnri7u8Xcl0bXc9jzTed3elugzpauMQMqa95SVlWnfvn2SpOrqapWU\nlIS3jR49WqdPn9bFixfl9/t1+PBhTZgwIeExN9xwgw4ePChJ2rdvnyZNmqTS0lJVVVWpublZdXV1\nOnXqlEpKSlRWVqbXXnstvO/EiRPVr18/fepTn9Lhw4clSYcOHdKYMWP0/vvv65prrtGWLVv03e9+\nV4ZhaMCAAXrzzTe1bNkyVVZWyuPx6LOf/ax8Pp/mzJmj+vp6OY6jgwcP0rYfAAAAWSFlJf233367\n9u/fr4ULF8pxHK1du1YvvfSSGhoatGDBAq1atUr33HOPHMfRvHnzNGzYsLjHSNLKlSt1//33a8OG\nDRo1apRmz54tj8ejiooKLVq0SI7jaNmyZcrNzVV5eblWrlyp8vJy5eTk6NFHH5UkrV27Vg899JCC\nwaA++clPavny5XIcRxs2bNCmTZuUm5ur1atXS5Kuu+46LV++XF6vV2PGjNHq1auVk5OjZcuW6e67\n75bX69XUqVN12223perxAQAAAD0mZUG/aZr68Y9/HLVu9OjR4d9nzZqlWbNmdXmM1BqEP/fccx3W\nz58/X/Pnz49al5eXp8cee6zDvp/5zGe0efPmDut//vOfd1g3btw47dy5s8P6O+64Q3fccUeH9QAA\nAEAmY3IuAAAAwOUI+gEAAACXI+gHAAAAXI6gHwAAAHA5gn4AAADA5Qj6AQAAAJcj6AcAAABcjqAf\nAAB0yjQMWaZHkmSZHpmGkeYUAegugn4AANApy7Q0/8bZ6md5Nf/G2bLMlM3tCSBF+KsFAABd+mbZ\nXH2zbG66kwHgMlHSDwAAALgcQT8AAADgcgT9AAAAgMsR9AMAAAAuR9APoFMM1QcAQPYj6AfQKYbq\nAwAg+/HtDaBLDNUHAEB2o6QfAAAAWY/mqJ0j6AcAAEDWozlq53gaAAAAcAWaoyZGST8AAOjTaBaC\nvoCgHwAA9Gk0C0FfwFsNAAD6PJqFwO0o6QcAAABcjqAfAPog2jADQN9C0A8AfRBtmAGgb+FTHgD6\nKNowA0DfQUk/AAAA4HIE/QAAAIDLEfQD3UQHSAAAkG0I+oFuogMkAACJUTiWmYhWgMtAB0gAAOIL\nFY7t/P0u3Tn28xSOZQj+FQAAANCjKBzLPDTvAQAAAFyOoB8AAABwOYJ+AAAAwOUI+gEAAACXI+gH\nAAAAXI6gHwCAK8S45AAyHUE/AABXiEn7AGQ6PpUAAOgBjEsOIJNR0g8AAAC4HEE/AAAA4HIE/QAA\nAIDLEfQDWYZRQgAAQHcR9ANZhlFCAJD5B9BdRAtAFmKUEKBvC2X+d/5+l+4c+3ky/wC6xKcEAABZ\niMw/gO5IWdBv27YefPBBnThxQl6vV2vWrNHIkSPD2/fs2aMnnnhClmVp3rx5mj9/fsJjTp8+rVWr\nVskwDI0ZM0YPPPCATNPUtm3btGXLFlmWpcWLF2vmzJlqamrSihUrdP78eeXn52v9+vUqLi7W6dOn\n9diCRdgAAA+OSURBVMADD6ilpUVer1cbNmxQUVGR1qxZoyNHjig/P1/Lly/XuHHjdObMGa1atUqO\n42j48OF6+OGHlZeXFzfNAAAA3RVqohWwgzTRQq9IWZv+Xbt2ye/3a+vWrfrBD36gRx55JLytpaVF\n69at0y9/+UtVVlZq69atOnfuXMJj1q1bp6VLl2rTpk1yHEe7d+9WbW2tKisrtWXLFj311FPasGGD\n/H6/Nm/erJKSEm3atEl33HGHNm7cKEm6//77tXTpUv3qV7/SwoUL9cEHH2jv3r16//339fzzz+tn\nP/uZHnroIUnST3/6Uy1cuFCbNm3SLbfcoqeffjphmgEAALqL/lnobSkL+quqqjR9+nRJ0vjx43Xs\n2LHwtlOnTmnEiBEaOHCgvF6vJk6cqEOHDiU8pqamRpMnT5YkzZgxQ2+++aaOHj2qCRMmyOv1qrCw\nUCNGjNDx48ejzjFjxgz99re/VVNTky5cuKC9e/eqoqJC1dXVKi0t1cmTJzV9+nSZpqni4mJ5PB7V\n1tbq5MmTmjFjhiSprKxMVVVVCdMMAABwOb5ZNlcv3/UEzbTQK1KWrfT5fCooKAgvezweBQIBWZYl\nn8+nwsLC8Lb8/Hz5fL6ExziOI6Ot2is/P191dXWdniO0PrTvpUuX9O677+q+++7T0qVL9aMf/Ugv\nvPCCxo4dq6efflp33XWXzp49q5MnT6qxsVFjx47Vnj17NHfuXO3evVuNjY0Jr9eZoqL+sizPlT1I\n9LqhQwu73gm9qjngj1oeMqRAuZY3Talp1xPvSqbeG3oWnyvd05f/LlLxrvTl5+lWl/OepCzoLygo\nUH19fXjZtm1ZlhV3W319vQoLCxMeY5pm1L4DBgxI6hyhfQcOHKj8/HxNmTJFkjRz5kzt379fX/nK\nV/TOO++ooqJCY8aM0Y033qhBgwZp5cqVevjhh7Vz507NmDFDRUVFCa/XmY8+aricR4c0Gjq0ULW1\ndelOBmL4gy1Ry+fO+eT15KQpNa166l3JxHtDz+Jzpfv66t9Fqt6VgB2I6j9w4Xy9LLO5x6+D3pHo\nPekqI5Cy5j1lZWXat2+fJKm6ulolJSXhbaNHj9bp06d18eJF+f1+HT58WBMmTEh4zA033KCDBw9K\nkvbt26dJkyaptLRUVVVVam5uVl1dnU6dOqWSkhKVlZXptddeC+87ceJE9evXT5/61Kd0+PBhSdKh\nQ4c0ZswYvf/++7rmmmu0ZcsWffe735VhGBowYIDefPNNLVu2TJWVlfJ4PPrsZz+bMM0AAACZjP4D\nkFJY0n/77bdr//79WrhwoRzH0dq1a/XSSy+poaFBCxYs0KpVq3TPPffIcRzNmzdPw4YNi3uMJK1c\nuVL333+/NmzYoFGjRmn27NnyeDyqqKjQokWL5DiOli1bptzcXJWXl2vlypUqLy9XTk6OHn30UUnS\n2rVr9dBDDykYDOqTn/ykli9fLsdxtGHDBm3atEm5ublavXq1JOm6667T8uXL5fV6NWbMGK1evVo5\nOTlx0wwAAJDpGOIVhuM4TroT4VZU52YfquEzkz/Yoi8+993w8n99bWPaq/p7snlPpt0behafK93X\nV/8ueFeQjIxr3gMAAAAgMxD0AwAAAC5H0A8AAAC4HEE/gIwXmq5eEtPVAwBwGQj6AWQ8hpsDAODK\n8M0JICsw3BwAAJePkn4AAADA5Qj6ASCN6K8AAOgNBP0AkEb0VwAA9Aa+XQAgzeivAABINUr6AQAA\nAJcj6AcAAABcjqAfAAAAcDmCfgAAAMDlCPoBAAAAlyPoBwAAAFyOoB8AAABwOYJ+AAAAwOUI+gEA\nAACXI+gHAAAAXI6gHwAAZBTTMGSZHkmSZXpkGkaaUwRkP4J+AACQUSzT0vwbZ6uf5dX8G2fLMq10\nJwnIevwVAQCAjPPNsrn6ZtncdCcDcA1K+gEAAACXI+gHAAAAXI6gHwAAAHA5gn4AAADA5Qj6AQAA\nAJcj6AcAAABcjqAfAAAAcDmCfgAAAMDlCPoBAAAAlyPoBwAAAFyOoB8AAABwOYJ+AAAAwOUMx3Gc\ndCcCAADg/2/v3mOqrv84jj+Ry9GlSJeNjRA7kTkvm0i1xRwMVsaoMxPOHEd2Duaa/pGWll1sCqME\njC6rxbqC4TrVOUDiIk1jeekUaakZrVzKCF3a0kjIDmeCcM7vD9dZ/sgD1k+/53d4Pf773j7nve/e\nHF7nc77n+xWRy0cz/SIiIiIiEU6hX0REREQkwin0i4iIiIhEOIV+EREREZEIp9AvIiIiIhLhFPpF\nRERERCKcQr+MOn6/n9LSUgoLC3E4HBw7duyC7Vu2bGHBggXYbDZKS0vx+/0GVSpGG65X/lRSUsLz\nzz9/hauTcDJcr3z77bcUFRWxcOFCHnroIfr6+gyqVIw2XK80NzeTn5+P1WrlvffeM6hKCSdtbW04\nHI4h63fu3InVaqWwsJCGhoZhx1Hol1Hnk08+ob+/n/r6elatWsUzzzwT3Hb27Fleeukl3n77bdxu\nN16vl127dhlYrRgpVK/8ye12c+TIEQOqk3ASqlcCgQAlJSWsX78el8tFZmYmJ06cMLBaMdJw7yvP\nPvssdXV1uFwu6urq+P333w2qVMJBTU0Na9euHTJRcO7cOdavX89bb72F0+mkvr6erq6ukGMp9Muo\nc+DAATIzMwFIS0vju+++C26Li4vD7XYzbtw4AAYGBjCZTIbUKcYL1SsAX3/9NW1tbRQWFhpRnoSR\nUL3S2dlJQkICGzduxG6309PTw4033mhUqWKw4d5Xpk6dyh9//EF/fz+BQICoqCgjypQwkZKSQnV1\n9ZD1HR0dpKSkMHHiROLi4rjlllvYt29fyLEU+mXU8Xq9jB8/PrgcHR3NwMAAAGPGjOG6664DwOl0\n4vP5mDNnjiF1ivFC9cqpU6d45ZVXKC0tNao8CSOheqW7u5uDBw9it9upq6tj79697Nmzx6hSxWCh\negVgypQpWK1W7rnnHrKzs4mPjzeiTAkTubm5xMTEDFnv9XqZMGFCcPmqq67C6/WGHEuhX0ad8ePH\n09vbG1z2+/0X/EH5/X6qqqpobW2lurpasyyjWKhe2b59O93d3SxdupQ333yTLVu20NTUZFSpYrBQ\nvZKQkMDkyZNJTU0lNjaWzMzMIbO7MnqE6pUffviB3bt3s2PHDnbu3Mnp06fZtm2bUaVKGPvvPurt\n7b3gQ8DfUeiXUSc9PR2PxwPAN998w80333zB9tLSUvr6+nj11VeDl/nI6BSqV4qLi2lqasLpdLJ0\n6VIsFgsFBQVGlSoGC9UrkyZNore3N/iDzf379zNlyhRD6hTjheqVCRMmMHbsWEwmE9HR0VxzzTWc\nOXPGqFIljKWmpnLs2DF6enro7+9n//79zJ49O+QxQ78vEIlwc+fOpbW1FZvNRiAQoLKykg8//BCf\nz8fMmTN5//33ufXWW1m0aBFwPtzNnTvX4KrFCKF6Rdfxy18N1ysVFRWsWrWKQCDA7Nmzyc7ONrpk\nMchwvVJYWEhRURGxsbGkpKSQn59vdMkSRv7aK6tXr+b+++8nEAhgtVpJTEwMeWxUIBAIXKE6RURE\nRETEALq8R0REREQkwin0i4iIiIhEOIV+EREREZEIp9AvIiIiIhLhFPpFRERERMJAW1sbDofjots9\nHg8OhwOHw4HdbmfatGl0dHSMaGzdslNERP5vuVwuABYuXGhwJSIi/05NTQ3Nzc0hnxGUlZVFVlYW\nALW1taSnp5Oamjqi8XXLThERERERg3388cdMnTqVxx9/nIaGBg4fPkx5eTlw/snelZWVwafu/vLL\nLyxZsoRNmzYRFxc3ovE10y8iIiM2MDBAWVkZ7e3tdHV1YTabefLJJ1m2bBlXX301JpOJefPmsXnz\nZnp6esjJycFisbBu3Tp8Ph+nT59m8eLF2O127rzzTjZs2IDZbMbn85GXl0dLSwsmk+lvX7uqqorW\n1laio6O54447WL58OdXV1QDMmTOHp556KrjvkSNHePHFF8nMzOTpp5+mvb2dwcFBlixZgsViuSLn\nSkTkUuTm5nL8+PHgcklJCZWVldx00000NjZSW1vLww8/DEBdXR333XffiAM/KPSLiMglOHjwILGx\nsdTX1+P3+1m0aBGffvopnZ2d1NbWkpycTFNTEydPnuSjjz4iJiaGiooKHnjgATIyMvjpp5+YN28e\nxcXFzJ8/n+bmZlasWEFLSwvZ2dkXDfwnTpzA4/GwdetW+vr6WLNmDX19fcHt6enpfPDBBwBs3LiR\nvXv3kpubywsvvMCMGTOoqqrC6/Vis9mYNWsWkyZNuiLnS0Tkn+ro6AhOZpw7d44bbrgBAL/fz+7d\nu4MfAEZKoV9EREbstttuIyEhgXfffZcff/yRo0eP4vP5uPbaa0lOTg7uN336dGJizv+LWb16NZ99\n9hlvvPEGhw8fxufzAVBQUMDixYtZsWIFmzdv5pFHHrno6yYmJmIymbDZbOTk5LBy5cq//YDw+eef\n09jYiNvtJioqii+++IKzZ8+yadMmAHw+H+3t7Qr9IhL2zGYzVVVVJCUlceDAAX799Vfg/DeZZrOZ\nsWPHXtJ4Cv0iIjJiO3bs4OWXX6a4uJiCggK6u7tJSkoa8s/nr8srV64kPj6enJwc7r77brZu3QpA\ncnIySUlJtLS08NtvvzFr1qyLvm5MTAyNjY189dVXeDwebDYbTqfzgn2OHj1KSUkJtbW1wete/X4/\nzz33HDNmzACgq6uLiRMn/k/OhYjI5VRWVsYTTzzBwMAAUVFRVFRUANDZ2fmPJi4U+kVEZMT27NlD\nXl4eVquVkydPsm/fPjIyMkIe09rayrZt20hMTKSpqQmAwcFBoqOjsVqtlJeXY7fbQ45x6NAh1q1b\nh9PpJCMjg0OHDtHZ2Rnc7vV6WbZsGWvWrLngTha33347LpeL8vJyTp06xfz583G73aSkpPyLsyAi\ncnkkJyfT0NAAwMyZM4dMbgDk5eWRl5d3yWMr9IuIyIgtWLCARx99lO3btxMXF0daWhpffvllyGMe\nfPBBioqKiI+Px2w2c/3113P8+HEmT57MXXfdxdq1a7n33ntDjjF9+nTS0tKwWCyMGzeOadOmkZWV\nxffffw/AO++8w88//8xrr70W/HFvfn4+y5cvp6ysDIvFwuDgII899pgCv4iMSrplp4iIGCIQCODx\neHC5XLz++utGlyMiEtE00y8iIoaorKxk165d1NTUBNc5HA7OnDkzZF+bzaYHcImI/Aua6RcRERER\niXBjjC5AREREREQuL4V+EREREZEIp9AvIiIiIhLhFPpFRERERCKcQr+IiIiISIRT6BcRERERiXD/\nAcz23P6B9XZSAAAAAElFTkSuQmCC\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x1243b9b00>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"sns.set(rc={'figure.figsize':(12,6)})\n",
"sns.regplot(x='array_size', y='run_time', data=empty_results_df,color=\"seagreen\",\n",
" x_bins=20,scatter_kws={\"alpha\":1},line_kws={\"alpha\":0.5});"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## O($N^{2}$) Quadratic Time\n",
"Quadratic time is common with algorithms that involve nested iterations over the data set. Deeper nested iterations will result in O($N^{2}$), O($N^{4}$) etc.This also includes simple sorting algorithms, such as bubble sort, selection sort, and insertion sort. Let's time a function that iterates over a list of integers to create a new list of the sum of i,j elements. "
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"range_spec = list(range(100, 1000, 10))\n",
"\n",
"def add_each_element_nested(range_spec):\n",
" list_of_times = []\n",
" \n",
" for routine in range_spec:\n",
" iter_list = list(range(routine)) # range is an iter in python3\n",
" start = time.time()\n",
" new_list = []\n",
" for i in iter_list:\n",
" for j in iter_list:\n",
" new_list.append(i + j)\n",
" end = time.time()\n",
" \n",
" list_of_times.append(end - start)\n",
" return list_of_times"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"x = pd.DataFrame({'run_time': add_each_element_nested(range_spec), 'array_size': range_spec})\n",
"# x = remove_outliers(zeros_results_df, 'run_time')"
]
},
{
"cell_type": "code",
"execution_count": 114,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x12516c5f8>"
]
},
"execution_count": 114,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAb0AAAGoCAYAAADSNTtsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3Xlw3OWB5/9331IfulvyIVm2Zck2EDAWhkDigE0cCCTZ\nDCbIwDg7G1dtTYqdqUxRyVBTUy62hjWemq3a3ZohZI7fbDYZQsyZ4IQkxNjBYC5fCtj4kGRblmxZ\nlnV3t6S+vr8/Wt1267KuVkvqz+ufpL9H99MPqv74eb7PYTIMw0BERCQDmNNdABERkZmi0BMRkYyh\n0BMRkYyh0BMRkYyh0BMRkYxhTXcBpqqtrTfdRZgR+flOOjsD6S7GnKS6mxrV39So/iZvsnXn9XpG\nPaeW3hxhtVrSXYQ5S3U3Naq/qVH9TV4q6i5loReNRtm+fTs1NTVs3bqVxsbGYdf09fWxZcsWGhoa\nEsf++Z//mZqaGh566CFefvnlVBVPREQyUMpCb8+ePQSDQXbt2sWTTz7Jzp07k85/+umnPP744zQ1\nNSWOffTRRxw9epQXX3yRn/70p1y6dClVxRMRkQyUstA7fPgw69evB2DNmjUcO3Ys6XwwGOS5555j\n+fLliWPvvfceVVVVPPHEE/z5n/8599xzT6qKJyIiGShlA1l8Ph9utzvx2mKxEA6HsVpjH1ldXT3s\nns7OTi5evMiPfvQjmpub+e53v8tvf/tbTCbTqJ+Tn+/MmD7zsR7OythUd1Oj+psa1d/kTXfdpSz0\n3G43fr8/8ToajSYCbzR5eXksX74cu93O8uXLcTgcdHR0UFhYOOo9mTIqyuv1ZMxI1emmupsa1d/U\nqP4mb7J1l5bRm2vXrmX//v0A1NbWUlVVdd17qqureffddzEMg9bWVvr6+sjLy0tVEUVEJMOkrKW3\nadMmDhw4wJYtWzAMgx07drB7924CgQA1NTUj3rNhwwYOHjzIww8/jGEYbN++HYslM7ouRUQk9Uxz\nfWuhTOk2UBfJ5Knupkb1NzWqv8mbU92bIiIis41CT0REMoZCT0REMoZCT0REMoZCT0REMsac31pI\nRESmrrnNR11TF72BEB6njcqyPEq97uvfOMco9EREMlxzm49DJy8nXnf7g4nX8y341L0pIpLh6pq6\nJnR8LlPoiYhkuN5AaELH5zKFnohIhvM4bRM6Ppcp9EREMlxl2cgL+492fC7TQBYRkQwXH6yi0Zsi\nIpIRSr3ueRlyQ6l7U0REMoZCT0REMoZCT0REMoZCT0REMoZCT0REMoZCT0REMoZCT0REMoZCT0RE\nMoZCT0REMoZCT0REMoZCT0REMoZCT0REMoZCT0REMoZCT0REMoZCT0REMoZCT0REMoZCT0REMoZC\nT0REMoZCT0REMoZCT0REMoZCT0REMoZCT0REMoZCT0REMoZCT0REMkbKQi8ajbJ9+3ZqamrYunUr\njY2Nw67p6+tjy5YtNDQ0JB1vb2/n7rvvHnZcRERkKlIWenv27CEYDLJr1y6efPJJdu7cmXT+008/\n5fHHH6epqSnpeCgUYvv27WRlZaWqaCIikqGsqXrjw4cPs379egDWrFnDsWPHks4Hg0Gee+45fvCD\nHyQd//u//3u2bNnCv/zLv4zrc/LznVitlukp9Czn9XrSXYQ5S3U3Naq/qVH9Td50113KQs/n8+F2\nuxOvLRYL4XAYqzX2kdXV1cPuee211ygoKGD9+vXjDr3OzsD0FHiW83o9tLX1prsYc5LqbmpUf1Oj\n+pu8ydbdWEGZsu5Nt9uN3+9PvI5Go4nAG82rr77K+++/z9atWzlx4gR//dd/TVtbW6qKKCIiGSZl\nLb21a9eyb98+HnjgAWpra6mqqrruPS+88ELi/2/dupWnn34ar9ebqiKKiEiGSVnobdq0iQMHDrBl\nyxYMw2DHjh3s3r2bQCBATU1Nqj5WRERkVCbDMIx0F2IqMqWvXM8FJk91NzWqv6lR/U3enHqmJyIi\nMtso9EREJGOk7JmeiIjIeDW3+ahr6qI3EMLjtFFZlpeS+Y0KPRERSbmRQq3U606cO3TycuLabn+Q\nQycvU5Dvwmk1TWs51L0pIiIpFQ+1bn+QqGEkQq25zQdAXVPXiPcdP9s+7WVR6ImISEqNFmrx472B\n0Ijnu33BaS+LQk9ERFJqtFCLH/c4bSOez3Xbp70sCj0REUmp0UItfryyLG/E8zcuK5z2smggi4iI\nDDPWwJOJqizLSxqocu1xIPG+Qz+vfGHOtE/sV+iJiEiSkUZT7j3cjNtpw2o2TzgERwu1a+8v8DjI\ndTtYt7oEd/bILcPpoNATEZEkQwee9PiDXGz3k9VjYenCnMToS2BCwTfatX0DYf7tVyfo9A1wQ3k+\n39qwYmpfYAx6piciIkmGDjxp7+kHYCAUTTo+2qjMiYgaBq++00CnbwCAPI9jyu85FoWeiIgkGTrw\n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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x123958e80>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"sns.set(rc={'figure.figsize':(7,7)})\n",
"sns.regplot(x='array_size', y='run_time', data=x,\n",
" scatter_kws={\"alpha\":.5},line_kws={\"alpha\":0.8},\n",
" lowess = True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## O($c^{N}$) where ${c>1}$ Exponential Time\n",
"We just covered O($N^{x}$) which is intuitive as you can easily picture the complexity tied to the number of x nested for loops. O(logn), which we will discuss later, is also intuitive as it splits the dataset in half everytime, such as binary search. I find O($2^{N}$) a little harder to understand. We know that the operation runs in exponential time, and that means it is impractical for any reasonably large input size n. Factorial combinatorics is a great general example as an arrangement of 10 characters has 3.6M candidates (10!) and adding only 1 letter, which represents a 10% increase in data size, increases the number of potential candidates by 11 (1000% increase). It is hard to imagine an algorithm where one additional data element can more than double the complexity. I found Towers of Hanoi to be one simple example, which is covered nicely by Brad Miller and David Ranum here: http://interactivepython.org/runestone/static/pythonds/Recursion/TowerofHanoi.html\n",
"\n",
"We'll work through an interactive example and graph the performance with `pyprof2calltree` https://github.com/pwaller/pyprof2calltree in part 2 of this blog post."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python [anaconda3]",
"language": "python",
"name": "Python [anaconda3]"
},
"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.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment