From c0e93527a590e9919185ae34abdbe9f09d2d8683 Mon Sep 17 00:00:00 2001 From: cvrse Date: Sat, 5 Sep 2026 10:15:13 +0300 Subject: [PATCH] [0] initial commit --- NeklyudovMS/428b.md | 0 NeklyudovMS/docs/Report 1.ipynb | 423 ++++++++ NeklyudovMS/docs/Report 2.ipynb | 938 ++++++++++++++++++ .../docs/data/task1/performance_plot.png | Bin 0 -> 68485 bytes NeklyudovMS/docs/data/task1/results.csv | 31 + NeklyudovMS/docs/data/task2/results.csv | 16 + NeklyudovMS/docs/data/task2/results2.csv | 7 + NeklyudovMS/task1/__init__.py | 0 NeklyudovMS/task1/structures/BinaryTree.py | 90 ++ NeklyudovMS/task1/structures/HashTable.py | 57 ++ NeklyudovMS/task1/structures/LinkedList.py | 65 ++ NeklyudovMS/task1/structures/__init__.py | 0 NeklyudovMS/task1/util/__init__.py | 0 NeklyudovMS/task1/util/randomNames.py | 55 + NeklyudovMS/task1/util/timeTester.py | 37 + NeklyudovMS/task2/__init__.py | 0 NeklyudovMS/task2/consoleView.py | 95 ++ NeklyudovMS/task2/mazeBuilder.py | 74 ++ NeklyudovMS/task2/mazeExamples/100x100.txt | 100 ++ NeklyudovMS/task2/mazeExamples/10x10.txt | 10 + NeklyudovMS/task2/mazeExamples/25x25.txt | 25 + NeklyudovMS/task2/mazeExamples/50x50.txt | 50 + NeklyudovMS/task2/mazeExamples/5x5.txt | 5 + .../mazeExamplesSpeical/maze_25x25_empty.txt | 25 + .../maze_25x25_wo_exit.txt | 25 + NeklyudovMS/task2/mazeObjects/__init__.py | 0 NeklyudovMS/task2/mazeObjects/cell.py | 13 + NeklyudovMS/task2/mazeObjects/maze.py | 41 + NeklyudovMS/task2/mazeObjects/path.py | 7 + NeklyudovMS/task2/mazeSolver.py | 70 ++ NeklyudovMS/task2/observerSubject.py | 43 + NeklyudovMS/task2/strategyObjects/AStar.py | 47 + NeklyudovMS/task2/strategyObjects/BFS.py | 43 + NeklyudovMS/task2/strategyObjects/DFS.py | 41 + NeklyudovMS/task2/strategyObjects/__init__.py | 0 .../strategyObjects/pathFindingStrategy.py | 14 + NeklyudovMS/task2/strategyObjects/util.py | 13 + NeklyudovMS/task2/tester.py | 84 ++ 38 files changed, 2544 insertions(+) create mode 100644 NeklyudovMS/428b.md create mode 100644 NeklyudovMS/docs/Report 1.ipynb create mode 100644 NeklyudovMS/docs/Report 2.ipynb create mode 100644 NeklyudovMS/docs/data/task1/performance_plot.png create mode 100644 NeklyudovMS/docs/data/task1/results.csv create mode 100644 NeklyudovMS/docs/data/task2/results.csv create mode 100644 NeklyudovMS/docs/data/task2/results2.csv create mode 100644 NeklyudovMS/task1/__init__.py create mode 100644 NeklyudovMS/task1/structures/BinaryTree.py create mode 100644 NeklyudovMS/task1/structures/HashTable.py create mode 100644 NeklyudovMS/task1/structures/LinkedList.py create mode 100644 NeklyudovMS/task1/structures/__init__.py create mode 100644 NeklyudovMS/task1/util/__init__.py create mode 100644 NeklyudovMS/task1/util/randomNames.py create mode 100644 NeklyudovMS/task1/util/timeTester.py create mode 100644 NeklyudovMS/task2/__init__.py create mode 100644 NeklyudovMS/task2/consoleView.py create mode 100644 NeklyudovMS/task2/mazeBuilder.py create mode 100644 NeklyudovMS/task2/mazeExamples/100x100.txt create mode 100644 NeklyudovMS/task2/mazeExamples/10x10.txt create mode 100644 NeklyudovMS/task2/mazeExamples/25x25.txt create mode 100644 NeklyudovMS/task2/mazeExamples/50x50.txt create mode 100644 NeklyudovMS/task2/mazeExamples/5x5.txt create mode 100644 NeklyudovMS/task2/mazeExamplesSpeical/maze_25x25_empty.txt create mode 100644 NeklyudovMS/task2/mazeExamplesSpeical/maze_25x25_wo_exit.txt create mode 100644 NeklyudovMS/task2/mazeObjects/__init__.py create mode 100644 NeklyudovMS/task2/mazeObjects/cell.py create mode 100644 NeklyudovMS/task2/mazeObjects/maze.py create mode 100644 NeklyudovMS/task2/mazeObjects/path.py create mode 100644 NeklyudovMS/task2/mazeSolver.py create mode 100644 NeklyudovMS/task2/observerSubject.py create mode 100644 NeklyudovMS/task2/strategyObjects/AStar.py create mode 100644 NeklyudovMS/task2/strategyObjects/BFS.py create mode 100644 NeklyudovMS/task2/strategyObjects/DFS.py create mode 100644 NeklyudovMS/task2/strategyObjects/__init__.py create mode 100644 NeklyudovMS/task2/strategyObjects/pathFindingStrategy.py create mode 100644 NeklyudovMS/task2/strategyObjects/util.py create mode 100644 NeklyudovMS/task2/tester.py diff --git a/NeklyudovMS/428b.md b/NeklyudovMS/428b.md new file mode 100644 index 0000000..e69de29 diff --git a/NeklyudovMS/docs/Report 1.ipynb b/NeklyudovMS/docs/Report 1.ipynb new file mode 100644 index 0000000..89b4d90 --- /dev/null +++ b/NeklyudovMS/docs/Report 1.ipynb @@ -0,0 +1,423 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "2acfa743", + "metadata": {}, + "source": [ + "# 0. Подготовим окружение" + ] + }, + { + "cell_type": "code", + "id": "4689b73e", + "metadata": { + "ExecuteTime": { + "end_time": "2026-09-04T06:25:55.150018Z", + "start_time": "2026-09-04T06:25:55.134797Z" + } + }, + "source": [ + "import sys\n", + "import os\n", + "sys.path.insert(0, os.path.abspath( '../task1'))\n", + "sys.path.insert(0, os.path.abspath( '../'))" + ], + "outputs": [], + "execution_count": 1 + }, + { + "cell_type": "markdown", + "id": "37cc11a5", + "metadata": {}, + "source": [ + "# 1. Генерация тестовых данных\n", + "\n", + "Создадим список records из N=10000 элементов. Каждый элемент — кортеж (name, phone). \n", + "Имена возъмём случайные из небольшого набора (чтобы были повторения и коллизии). \n", + "Для проверки влияния порядка подготовим два варианта: \n", + "\n", + "_records_shuffled_ — случайный порядок. \n", + "_records_sorted_ — отсортированный по имени (по алфавиту)." + ] + }, + { + "cell_type": "code", + "id": "a3b5c31b", + "metadata": { + "ExecuteTime": { + "end_time": "2026-09-04T06:25:55.231512Z", + "start_time": "2026-09-04T06:25:55.159161Z" + } + }, + "source": [ + "from util.randomNames import generate_test_data\n", + "from util.timeTester import test\n", + "\n", + "records_shuffled = generate_test_data(N=10000)\n", + "records_sorted = generate_test_data(N=10000, _sorted=True)" + ], + "outputs": [], + "execution_count": 2 + }, + { + "cell_type": "markdown", + "id": "c2f4989c", + "metadata": {}, + "source": [ + "# 2. Проведение замеров" + ] + }, + { + "cell_type": "code", + "id": "df12d41d", + "metadata": { + "ExecuteTime": { + "end_time": "2026-09-04T06:25:55.250684Z", + "start_time": "2026-09-04T06:25:55.233856Z" + } + }, + "source": [ + "# Подготовим функции СД, которые будем тестировать\n", + "from structures.LinkedList import *\n", + "from structures.HashTable import *\n", + "from structures.BinaryTree import *\n", + "\n", + "func_list = {\"Связанный список\" : (ll_insert, ll_find, ll_delete),\n", + " \"Хэш-таблица\" : (ht_insert, ht_find, ht_delete),\n", + " \"Бинарное дерево\" : (bst_insert, bst_find, bst_delete)}" + ], + "outputs": [], + "execution_count": 3 + }, + { + "cell_type": "code", + "id": "cc8d0436", + "metadata": { + "ExecuteTime": { + "end_time": "2026-09-04T06:25:57.233606Z", + "start_time": "2026-09-04T06:25:55.260869Z" + } + }, + "source": [ + "# Проведём замеры\n", + "report = [[\"Структура\", \"Режим\", \"Вставка\", \"Поиск\", \"Удаление\"]]\n", + "records = {\"Cлучайный\" : records_shuffled, \"Отсортированный\" : records_sorted}\n", + "\n", + "TEST_ITERATIONS_NUM = 5\n", + "\n", + "for _ in range(TEST_ITERATIONS_NUM):\n", + " for mode, data in records.items():\n", + " for struct_name, fns in func_list.items():\n", + " result = test(data, *fns)\n", + " row = [struct_name, mode,\n", + " result[\"insert_time\"],\n", + " result[\"find_time\"],\n", + " result[\"delete_time\"]]\n", + " report.append(row)" + ], + "outputs": [], + "execution_count": 4 + }, + { + "cell_type": "code", + "id": "2eedf056", + "metadata": { + "ExecuteTime": { + "end_time": "2026-09-04T06:25:57.277790Z", + "start_time": "2026-09-04T06:25:57.266011Z" + } + }, + "source": [ + "# Сохраним данные в csv\n", + "import csv\n", + "with open(\"data/task1/results.csv\", \"w\", newline=\"\") as f:\n", + " writer = csv.writer(f)\n", + " writer.writerows(report)" + ], + "outputs": [], + "execution_count": 5 + }, + { + "cell_type": "markdown", + "id": "94335af1", + "metadata": {}, + "source": [ + "# 3. Построение графиков и их анализ" + ] + }, + { + "cell_type": "code", + "id": "cad64d2f", + "metadata": { + "ExecuteTime": { + "end_time": "2026-09-04T06:25:58.231489Z", + "start_time": "2026-09-04T06:25:57.280067Z" + } + }, + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "df = pd.read_csv('data/task1/results.csv')\n", + "mean_times = df.groupby(['Структура', 'Режим'])[['Вставка', 'Поиск', 'Удаление']].mean().reset_index()\n", + "structures = mean_times['Структура'].unique()\n", + "modes = mean_times['Режим'].unique()\n", + "\n", + "fig, axes = plt.subplots(1, 3, figsize=(15, 5))\n", + "operations = ['Вставка', 'Поиск', 'Удаление']\n", + "\n", + "for ax, op in zip(axes, operations):\n", + " # a\n", + " x = np.arange(len(structures))\n", + " width = 0.35\n", + " \n", + " random_vals = []\n", + " sorted_vals = []\n", + " for s in structures:\n", + " random_row = mean_times[(mean_times['Структура']==s) & (mean_times['Режим']=='Cлучайный')]\n", + " sorted_row = mean_times[(mean_times['Структура']==s) & (mean_times['Режим']=='Отсортированный')]\n", + " random_vals.append(random_row[op].values[0] if not random_row.empty else 0)\n", + " sorted_vals.append(sorted_row[op].values[0] if not sorted_row.empty else 0)\n", + " \n", + " ax.bar(x - width/2, random_vals, width, label='Случайный')\n", + " ax.bar(x + width/2, sorted_vals, width, label='Отсортированный')\n", + " ax.set_xticks(x)\n", + " ax.set_xticklabels(structures)\n", + " ax.set_ylabel('Время (сек)')\n", + " ax.set_title(op)\n", + " ax.legend()\n", + "\n", + "plt.tight_layout()\n", + "plt.savefig('data/task1/performance_plot.png', dpi=150)\n", + "plt.show()" + ], + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "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d+5MMU7qww8/rGPH0qbdAABktLTKxUmWL1+hokWKyLevjxk6zeo9/uZbbys+Pt42dEpCwjVbfGhomLp2665+fr5mQu9Dhw6rvXcHRUVF2WKmTP1U+fPn1+jRI1WoUCGFhISYY168eNEW0617Dw0fNlRBixeaSdRWr/5WAwcNtm23et21adtew4Z+pK++Wqpz585p06bN+vCjoWl6/QAAOEtOBwAAmaSIft99hfXnn6fM38WLP6A3W7c2k36tXbfeTPqV0T3fpn76uT77dIq2bduurVt/1PO1n9PLL7+kpk2b3+qlAgCQKaVlLk4ye85cs6SmabOUOXTlylVmuZGAMWPN4sipU6dMMf5GrF7pHTt1vmEMAABZVXrkdAAAkIFF9EcffVRz58xS8eLFdejQIXV5r6sWzJ9neplZvcc6duygTp3etfUqz6ieb2vWrJG//wB1695VQz/6SAcPHlDHjp31U0jIzX8qAABkQumRiwEAwN1HTgcAIGtJnInzJgx8f4D27dun119vqq0//qi5c+dow4aNKv/o43rs8f9q/vwF6trtvVtugNXr7elqz6jMwx5q2Kix6ZGevOdb79597OKtXm81a9U28S+8+JIZT/V6ixYvlpdXLZX1eEQv16mntevW3XK7AADIbNIrFwMAgLuLnA4AgJP2RK9U6Uk1a95Ce/fu057ISL315puaM/cLM16pZdas2VqxYll6thUAgGyNXAwAgHMgpwMA4KQ90QsXLqzY2DjztzWxl7X873//s20/9b//qWDBgunTSgAAQC4GAMBJkNMBAHDSIrol6a64o/cAACB9kYsBAHAO5HQAAJxwOBfLhAnjdOniJfN33rx5NWrkx+aOuSVP3jzp00IAAGBDLgYAwDmQ0wEAyDpuuoi+ZMlSu/dfffW1fcBpaenSL9OsYQAAwB65GAAA50BOBwDASYvovfv4pG9LAADADZGLAQBwDumZ09u2aaMuXTrLzc1NkZF7NXDQYP38888O4xs2bCA/374qWbKkDh06rOEjRmjjxk12Mb59fdS6dSsVKvQfhYaGyL//ABObfIz3YUM/0ssvv6SEhAStXv2tBg0eYutZX7bswxo58mOVe+QR3XvvvTp+/Li+/maZxo0brytXrqTbZwEAQIaMiQ4AAAAAADKnxo0baciQQRo3boLq1quvyMhIBS6Yp6JFi6YaX7Wq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" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 6 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2026-09-04T06:25:59.106420Z", + "start_time": "2026-09-04T06:25:58.256204Z" + } + }, + "cell_type": "code", + "source": [ + "import sys\n", + "!{sys.executable} -m pip install pandas numpy matplotlib\n" + ], + "id": "c677a727d4516f1e", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: pandas in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (2.3.3)\n", + "Requirement already satisfied: numpy in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (2.0.2)\n", + "Requirement already satisfied: matplotlib in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (3.9.4)\n", + "Requirement already satisfied: python-dateutil>=2.8.2 in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (from pandas) (2.9.0.post0)\n", + "Requirement already satisfied: pytz>=2020.1 in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (from pandas) (2026.3.post1)\n", + "Requirement already satisfied: tzdata>=2022.7 in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (from pandas) (2026.3)\n", + "Requirement already satisfied: contourpy>=1.0.1 in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (from matplotlib) (1.3.0)\n", + "Requirement already satisfied: cycler>=0.10 in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (from matplotlib) (0.12.1)\n", + "Requirement already satisfied: fonttools>=4.22.0 in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (from matplotlib) (4.60.2)\n", + "Requirement already satisfied: kiwisolver>=1.3.1 in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (from matplotlib) (1.4.7)\n", + "Requirement already satisfied: packaging>=20.0 in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (from matplotlib) (26.3)\n", + "Requirement already satisfied: pillow>=8 in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (from matplotlib) (11.3.0)\n", + "Requirement already satisfied: pyparsing>=2.3.1 in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (from matplotlib) (3.3.2)\n", + "Requirement already satisfied: importlib-resources>=3.2.0 in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (from matplotlib) (6.5.2)\n", + "Requirement already satisfied: zipp>=3.1.0 in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (from importlib-resources>=3.2.0->matplotlib) (3.23.1)\n", + "Requirement already satisfied: six>=1.5 in /Users/cvrse/Desktop/пересдача/.venv/lib/python3.9/site-packages (from python-dateutil>=2.8.2->pandas) (1.17.0)\n" + ] + } + ], + "execution_count": 7 + }, + { + "cell_type": "code", + "id": "1d86131d", + "metadata": { + "ExecuteTime": { + "end_time": "2026-09-04T06:25:59.170550Z", + "start_time": "2026-09-04T06:25:59.127903Z" + } + }, + "source": [ + "df = pd.read_csv('data/task1/results.csv')\n", + "df.groupby(['Структура', 'Режим'])[['Вставка', 'Поиск', 'Удаление']].mean().reset_index()" + ], + "outputs": [ + { + "data": { + "text/plain": [ + " Структура Режим Вставка Поиск Удаление\n", + "0 Бинарное дерево Cлучайный 0.008477 0.000095 0.000073\n", + "1 Бинарное дерево Отсортированный 0.089950 0.000914 0.000636\n", + "2 Связанный список Cлучайный 0.067483 0.000662 0.000383\n", + "3 Связанный список Отсортированный 0.133676 0.001328 0.000733\n", + "4 Хэш-таблица Cлучайный 0.042672 0.000473 0.000228\n", + "5 Хэш-таблица Отсортированный 0.044273 0.000492 0.000236" + ], + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
СтруктураРежимВставкаПоискУдаление
0Бинарное деревоCлучайный0.0084770.0000950.000073
1Бинарное деревоОтсортированный0.0899500.0009140.000636
2Связанный списокCлучайный0.0674830.0006620.000383
3Связанный списокОтсортированный0.1336760.0013280.000733
4Хэш-таблицаCлучайный0.0426720.0004730.000228
5Хэш-таблицаОтсортированный0.0442730.0004920.000236
\n", + "
" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 8 + }, + { + "cell_type": "markdown", + "id": "c9a486a5", + "metadata": {}, + "source": [ + "# 4. Анализ результатов\n", + "---\n", + "### 4.1 Влияние порядка данных на вставку в BST\n", + "При вставке элементов в отсортированном порядке в бинарное дерево оно превращается в связный список - это связанно с тем, что все элементы вставляются в одну ветвь дерева. Сложность всех операций приблтижается к **O(n)**. Вставка в BST на отсортированных данных заняла 0.122171c вместо 0.011921с, разница более чем в 10 раз. Причём, время вставки даже хуже, чем у чистого связнного списка - это связанно с дополнительными расходами бинарного дерева. Поиск так же ухудшился, примерно в 10 раз, а с ним ухудшилось и удаление.\n", + "\n", + "### 4.2 Почему хэш-таблица почти не чувствительна к порядку\n", + "По графикам видно, что для хэш-таблицы время операций почти не изменяется. Исключение составляет лишь поиск, его время больше на отсортированных данных. Это связано с особенностями теста - поиск 10 несуществующих записей ухудшают результат для отсортированных данных. Все эти наблюдения связаны с механизмом работы хэш-таблицы - она распределяет данные по корзинам независимо от порядка поступления. Получается, что сложность всех операций **O(1)**\n", + "\n", + "### 4.3 Почему связный список всегда медленен при поиске\n", + "Для поиска в связном списке нужно просматривать все элементы по порядку, так что сложность всех операций **O(n)**\n", + "\n", + "### 4.4 Сравнение удаления\n", + "\n", + "- **Связаный список** удаление требует сначала найти элемент за O(n), затем переставить ссылки за O(1). Время удаления (0.000605 с) близко ко времени поиска, что логично.\n", + "- **Хеш-таблица:** при удалении, поиск корзины за O(1) и поиск в коротком связаном списке за O(n) удаляется элемент. Время удаления (0.000324) меньше, чем в списке.\n", + "- **BST:** на случайных данных удаление очень быстрое (0.000137 с) благодаря логарифмической высоте. На отсортированных данных время возрастает до 0.000873, что отражает деградацию до O(n)." + ] + }, + { + "cell_type": "markdown", + "id": "a7ed5470", + "metadata": {}, + "source": [ + "# 5. Вывод\n", + "На основе полученных результатов можно сформулировать следующие рекомендации:\n", + "\n", + "- Хеш-таблица – хороший выбор, если приоритетом является максимальная скорость вставки, поиска и удаления по ключу, а порядок элементов не имеет значения. Время операций близко к **O(1)** и практически не зависит от упорядоченности входных данных. Идеальна для кэшей, словарей и частых запросов по идентификатору.\n", + "\n", + "- Двоичное дерево поиска – следует применять, когда необходимо получать данные в отсортированном порядке. На случайных данных демонстрирует хорошую производительность **O(log n)**, однако при поступлении заранее отсортированных элементов вырождается в связный список с падением скорости до **O(n)**.\n", + "\n", + "- Связный список – демонстрирует линейную сложность поиска и удаления **O(n)** что делает его непригодным для задач с частым доступом к произвольным элементам. Может быть оправдан только в узких случаях, где вставки и удаления происходят исключительно в начале или конце коллекции (очереди, стеки) и не требуется поиск.\n", + "\n", + "Таким образом, для реальных задач чаще всего выбирают хеш-таблицы или сбалансированные деревья в зависимости от требований к упорядоченности данных.\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "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.14.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/NeklyudovMS/docs/Report 2.ipynb b/NeklyudovMS/docs/Report 2.ipynb new file mode 100644 index 0000000..bf305c8 --- /dev/null +++ b/NeklyudovMS/docs/Report 2.ipynb @@ -0,0 +1,938 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "6dc3ad27", + "metadata": {}, + "source": [ + "# Отчёт: Поиск выхода из лабиринта (объектно-ориентированная реализация с паттернами)\n", + "\n", + "- Описание задачи и выбранных паттернов (с диаграммой классов из Mermaid).\n", + "- Результаты экспериментов (таблицы, графики).\n", + "- Анализ эффективности алгоритмов и применимости паттернов.\n", + "- Выводы: как ООП и паттерны помогли сделать код гибким и расширяемым. Что было бы сложно изменить без них." + ] + }, + { + "cell_type": "markdown", + "id": "59b2f0d3", + "metadata": {}, + "source": [ + "## 1. Описание задачи и выбранных паттернов\n", + "\n", + "Необходимо создать программу с применением паттернов ООП для решения задачи поиска из лабиринта. Для этого, подготовим схему из Mermaid, отражающую связи между объектами:\n", + "\n", + "```mermaid\n", + "classDiagram\n", + " class Maze {\n", + " -Cell[] cells\n", + " -int width, height\n", + " -Cell start\n", + " -Cell exit\n", + " +getCell(x,y): Cell\n", + " +getNeighbors(cell): List~Cell~\n", + " }\n", + " \n", + " class Cell {\n", + " -int x, y\n", + " -bool isWall\n", + " -bool isStart\n", + " -bool isExit\n", + " +isPassable(): bool\n", + " }\n", + " \n", + " class MazeBuilder {\n", + " <>\n", + " +buildFromFile(filename): Maze\n", + " }\n", + " \n", + " class TextFileMazeBuilder {\n", + " +buildFromFile(filename): Maze\n", + " }\n", + " \n", + " class PathFindingStrategy {\n", + " <>\n", + " +findPath(maze, start, exit): List~Cell~\n", + " }\n", + " \n", + " class BFS\n", + " class DFS\n", + " class AStar\n", + " \n", + " class SearchStats {\n", + " +timeMs: float\n", + " +visitedCells: int\n", + " +pathLength: int\n", + " }\n", + " \n", + " class MazeSolver {\n", + " -Maze maze\n", + " -PathFindingStrategy strategy\n", + " +setStrategy(strategy)\n", + " +solve(): SearchStats\n", + " }\n", + " \n", + " class Observer {\n", + " <>\n", + " +update(event)\n", + " }\n", + " \n", + " class ConsoleView {\n", + " +update(event)\n", + " +render(maze, player, path)\n", + " }\n", + " \n", + " MazeBuilder <|.. TextFileMazeBuilder\n", + " MazeBuilder --> Maze : creates\n", + " PathFindingStrategy <|.. BFS\n", + " PathFindingStrategy <|.. DFS\n", + " PathFindingStrategy <|.. AStarStrategy\n", + " MazeSolver --> PathFindingStrategy : uses\n", + " MazeSolver --> Maze : uses\n", + " Observer <|.. ConsoleView\n", + " MazeSolver --> Observer : notifies\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "e268fdf0", + "metadata": {}, + "source": [ + "Builder — позволяет отделить создание сложного объекта от его представления. \n", + "Strategy — позволяет инкапсулировать разные алгоритмы поиска пути так, чтобы их можно было подставлять динамически. \n", + "Observer — позволяет обеспечить реакцию отображения на изменения состояния без жёсткой привязки. \n", + "\n", + "Код можно найти в репозитории: http://31.128.43.79:3000/musinaa/2026-rff_mp" + ] + }, + { + "cell_type": "markdown", + "id": "6ffa70d6", + "metadata": {}, + "source": [ + "# 2. Практическая часть\n", + "# 2.0 Подготовим окружение" + ] + }, + { + "cell_type": "code", + "id": "d457dda4", + "metadata": { + "ExecuteTime": { + "end_time": "2026-09-03T22:09:49.060242Z", + "start_time": "2026-09-03T22:09:49.026865Z" + } + }, + "source": [ + "import sys\n", + "import os\n", + "sys.path.insert(0, os.path.abspath( '../'))\n", + "\n", + "from task2.mazeBuilder import TextFileMazeBuilder\n", + "from task2.tester import Tester" + ], + "outputs": [], + "execution_count": 1 + }, + { + "cell_type": "markdown", + "id": "888f0e3c", + "metadata": {}, + "source": [ + "## 2.1 Данные для анализа\n", + "\n", + "В папке `mazeExamples` лежит несколько лабиринтов разных размеров: 5x5, 10x10, 50x50, 100x100. Для каждого лабиринта будем искать путь с помощью всех доступных алгоритмов поиска: BFS, DFS и A*. Измерения будем проводить 10 раз, а затем усреднённое значение записывать." + ] + }, + { + "cell_type": "code", + "id": "22ac68eb", + "metadata": { + "ExecuteTime": { + "end_time": "2026-09-03T22:09:49.511112Z", + "start_time": "2026-09-03T22:09:49.074074Z" + } + }, + "source": [ + "builder = TextFileMazeBuilder()\n", + "tester = Tester(builder, \"docs/data/task2/results.csv\")\n", + "tester.setTestingDirectory(\"task2/mazeExamples\")\n", + "tester.test()\n", + "tester.saveCSV()" + ], + "outputs": [], + "execution_count": 2 + }, + { + "cell_type": "markdown", + "id": "27441b5f", + "metadata": {}, + "source": [ + "## 2.2 Данные по лабиринтам и графики" + ] + }, + { + "cell_type": "code", + "id": "702c1844", + "metadata": { + "ExecuteTime": { + "end_time": "2026-09-03T22:09:49.771721Z", + "start_time": "2026-09-03T22:09:49.512480Z" + } + }, + "source": [ + "import pandas as pd\n", + "\n", + "df = pd.read_csv(\"data/task2/results.csv\")\n", + "for name in [\"5x5\", \"10x10\", \"50x50\", \"100x100\"]:\n", + " print(f\"\\n Лабиринт {name}\")\n", + " display(df[df[\"Лабиринт\"] == name].set_index(\"Алгоритм\"))" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + " Лабиринт 5x5\n" + ] + }, + { + "data": { + "text/plain": [ + " Лабиринт Время (мс) Посещённые клетки Длинна пути\n", + "Алгоритм \n", + "BFS 5x5 0.070421 8 7\n", + "DFS 5x5 0.019817 8 7\n", + "AStar 5x5 0.023188 8 7" + ], + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ЛабиринтВремя (мс)Посещённые клеткиДлинна пути
Алгоритм
BFS5x50.07042187
DFS5x50.01981787
AStar5x50.02318887
\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + " Лабиринт 10x10\n" + ] + }, + { + "data": { + "text/plain": [ + " Лабиринт Время (мс) Посещённые клетки Длинна пути\n", + "Алгоритм \n", + "BFS 10x10 0.334054 53 23\n", + "DFS 10x10 0.079800 35 31\n", + "AStar 10x10 0.076250 23 23" + ], + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ЛабиринтВремя (мс)Посещённые клеткиДлинна пути
Алгоритм
BFS10x100.3340545323
DFS10x100.0798003531
AStar10x100.0762502323
\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + " Лабиринт 50x50\n" + ] + }, + { + "data": { + "text/plain": [ + " Лабиринт Время (мс) Посещённые клетки Длинна пути\n", + "Алгоритм \n", + "BFS 50x50 3.734350 640 427\n", + "DFS 50x50 2.704262 995 435\n", + "AStar 50x50 1.655029 496 427" + ], + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ЛабиринтВремя (мс)Посещённые клеткиДлинна пути
Алгоритм
BFS50x503.734350640427
DFS50x502.704262995435
AStar50x501.655029496427
\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + " Лабиринт 100x100\n" + ] + }, + { + "data": { + "text/plain": [ + " Лабиринт Время (мс) Посещённые клетки Длинна пути\n", + "Алгоритм \n", + "BFS 100x100 12.758183 2495 1171\n", + "DFS 100x100 8.950550 3219 1243\n", + "AStar 100x100 4.468517 1286 1171" + ], + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ЛабиринтВремя (мс)Посещённые клеткиДлинна пути
Алгоритм
BFS100x10012.75818324951171
DFS100x1008.95055032191243
AStar100x1004.46851712861171
\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 3 + }, + { + "cell_type": "markdown", + "id": "c7a1b48e", + "metadata": {}, + "source": [ + "Как видно из таблиц, A* рекордно низкое врея выполнения, а так же хорошая длинна пути, часто совпадающая с медленными алгоритмами вроде BFS. Примечательно, что у A* всегда посещает меньше клеток, чем остальные алгоритмы, сильнее всего это заметно на большом лабиринте в 100 клеток, где разрыв от BFS: примерно в 2 раза меньше посещённых клеток, с DFS и вовсе почти в 3 раза.\n", + "\n" + ] + }, + { + "cell_type": "code", + "id": "d5078321", + "metadata": { + "ExecuteTime": { + "end_time": "2026-09-03T22:09:49.859382Z", + "start_time": "2026-09-03T22:09:49.774267Z" + } + }, + "source": [ + "tester.setTestingDirectory(\"task2/mazeExamplesSpeical\")\n", + "tester.writefile = \"../docs/data/task2/results2.csv\"\n", + "tester.test()\n", + "tester.saveCSV()\n", + "\n", + "df = pd.read_csv(\"data/task2/results2.csv\")\n", + "for name in [\"maze_25x25_wo_exit\", \"maze_25x25_empty\"]:\n", + " print(f\"\\n Лабиринт {name}\")\n", + " display(df[df[\"Лабиринт\"] == name].set_index(\"Алгоритм\"))" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + " Лабиринт maze_25x25_wo_exit\n" + ] + }, + { + "data": { + "text/plain": [ + " Лабиринт Время (мс) Посещённые клетки Длинна пути\n", + "Алгоритм \n", + "BFS maze_25x25_wo_exit 0.0 0 -1\n", + "DFS maze_25x25_wo_exit 0.0 0 -1\n", + "AStar maze_25x25_wo_exit 0.0 0 -1" + ], + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ЛабиринтВремя (мс)Посещённые клеткиДлинна пути
Алгоритм
BFSmaze_25x25_wo_exit0.00-1
DFSmaze_25x25_wo_exit0.00-1
AStarmaze_25x25_wo_exit0.00-1
\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + " Лабиринт maze_25x25_empty\n" + ] + }, + { + "data": { + "text/plain": [ + " Лабиринт Время (мс) Посещённые клетки Длинна пути\n", + "Алгоритм \n", + "BFS maze_25x25_empty 4.057983 625 49\n", + "DFS maze_25x25_empty 1.152621 625 337\n", + "AStar maze_25x25_empty 0.199208 49 49" + ], + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ЛабиринтВремя (мс)Посещённые клеткиДлинна пути
Алгоритм
BFSmaze_25x25_empty4.05798362549
DFSmaze_25x25_empty1.152621625337
AStarmaze_25x25_empty0.1992084949
\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 4 + }, + { + "cell_type": "markdown", + "id": "41192153", + "metadata": {}, + "source": [ + "Из выходных данных видно, что A* всегда быстро находит путь в пустом лабиринте, в реальных системах это очень большой плюс. BFS и BFS, из-за своей особенности пытается найти кратчайший путь и ему приходится оббегать весь лабиринт в поисках оптимального пути. \n", + "\n", + "Для того, чтобы оценить различия в алгоритмах на обычных лабиринтах нагляднее, построем серию графиков." + ] + }, + { + "cell_type": "code", + "id": "43409471", + "metadata": { + "ExecuteTime": { + "end_time": "2026-09-03T22:09:50.094662Z", + "start_time": "2026-09-03T22:09:49.872357Z" + } + }, + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "df = pd.read_csv(\"data/task2/results.csv\")\n", + "\n", + "size_order = [\"5x5\", \"10x10\", \"50x50\", \"100x100\"]\n", + "algo_order = [\"BFS\", \"DFS\", \"AStar\"]\n", + "colors = {\"BFS\": \"blue\", \"DFS\": \"green\", \"AStar\": \"orange\"}\n", + "\n", + "x = range(len(size_order))\n", + "fig, axes = plt.subplots(1, 3, figsize=(15, 4))\n", + "\n", + "params = [\"Время (мс)\", \"Посещённые клетки\", \"Длинна пути\"]\n", + "titles = [\"Время выполнения (мс)\", \"Посещённые клетки\", \"Длина пути\"]\n", + "\n", + "for i, (param, title) in enumerate(zip(params, titles)):\n", + " ax = axes[i]\n", + " for algo in algo_order:\n", + " values = []\n", + " for s in size_order:\n", + " val = df[(df[\"Алгоритм\"] == algo) & (df[\"Лабиринт\"] == s)][param].values\n", + " if len(val) > 0:\n", + " values.append(val[0])\n", + " else:\n", + " values.append(None)\n", + " ax.plot(x, values, marker='o', label=algo, color=colors[algo], linewidth=2, markersize=6)\n", + " ax.set_xticks(x)\n", + " ax.set_xticklabels(size_order)\n", + " ax.set_title(title)\n", + " ax.set_xlabel(\"Размер лабиринта\")\n", + " if i == 0:\n", + " ax.set_ylabel(\"Значение\")\n", + " ax.grid(True, linestyle='--', alpha=0.7)\n", + "\n", + "# Общая легенда сверху\n", + "handles, labels = axes[0].get_legend_handles_labels()\n", + "fig.legend(handles, labels, loc='upper center', bbox_to_anchor=(0.5, 1.05), ncol=3)\n", + "plt.tight_layout()\n", + "plt.show()" + ], + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "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" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 5 + }, + { + "cell_type": "markdown", + "id": "c573b32b", + "metadata": {}, + "source": [ + "## 3. Применение паттерна Observer\n", + "\n", + "Для того, чтобы продемонстрировать работу этого паттерна необходимо иметь возможность очищать вывод, но в Jupyter такой возможности нет. В терминале всё работает корректно." + ] + }, + { + "cell_type": "code", + "id": "898e8536", + "metadata": { + "ExecuteTime": { + "end_time": "2026-09-03T22:09:50.116844Z", + "start_time": "2026-09-03T22:09:50.098009Z" + } + }, + "source": [ + "from task2.consoleView import ConsoleView\n", + "from task2.mazeSolver import MazeSolver\n", + "from task2.strategyObjects.AStar import AStar\n", + "\n", + "maze = builder.buildFromFile(\"../task2/mazeExamples/25x25.txt\")\n", + "console = ConsoleView(maze)\n", + "solver = MazeSolver(AStar(), maze)\n", + "solver.attach(console)\n", + "console.render()" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001B[H\u001B[2J\u001B[48;5;9m\u001B[38;5;7mS\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + "\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + "\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + "\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;12m\u001B[38;5;7mE\u001B[0m\n", + "\n" + ] + } + ], + "execution_count": 6 + }, + { + "cell_type": "code", + "id": "aa5a4c8c", + "metadata": { + "ExecuteTime": { + "end_time": "2026-09-03T22:09:50.143321Z", + "start_time": "2026-09-03T22:09:50.124383Z" + } + }, + "source": [ + "# При нахождении решения рендер должен произойти автоматически\n", + "_ = solver.solve()" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001B[H\u001B[2J\u001B[48;5;9m\u001B[38;5;7mS\u001B[0m \u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + "\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + "\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;196m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + "\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + "\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;161m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\n", + "\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + "\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + "\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\n", + "\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\n", + "\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\n", + "\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;91m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\n", + "\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + "\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \n", + " \u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;126m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m \u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;56m\u001B[38;5;10m+\u001B[0m\u001B[48;5;7m\u001B[38;5;7m#\u001B[0m\u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\u001B[48;5;21m\u001B[38;5;10m+\u001B[0m\u001B[48;5;12m\u001B[38;5;7mE\u001B[0m\n", + "\n" + ] + } + ], + "execution_count": 7 + }, + { + "cell_type": "markdown", + "id": "484b4ef6", + "metadata": {}, + "source": [ + "## 4. Применимость паттернов\n", + "После выполнения работы можно оценить, насколько для этого помогли паттерны ООП. \n", + "Самый полезный паттерн - это конечно Strategy. Он позволил без лишней мороки провести замеры серийно, не используя каждый алгоритм вручную. \n", + " \n", + "Вторым по значимости я бы назвал Observer, он позволил сделать рендер лабиринта проще, однако сильнее всего оценить его получилось бы совместно с паттерном Commad и игроком с передвижениями. Его я не успел реализовать.\n", + " \n", + "Третий - Builder. В этой работе его преимущества оценить трудно из-за того, что использовался только один формат файла - plaintext. Однако, если понадобится искать пути в больших лабиринтах, то их придётся хрвнить в другом формате, например бинарном, и тогда преимщества паттерна Builder станут очевидны. \n", + " \n", + "Так же я создал класс-оркестратор MazeSolver, который помог перенести почти весь код тестов в одно место и удобно эти тесты использовать. Этот паттерн я так же считаю полезным. " + ] + }, + { + "cell_type": "markdown", + "id": "d4026233", + "metadata": {}, + "source": [ + "## 5. Вывод\n", + "Применение объектно-ориентированного подхода и паттернов проектирования позволило разделить ответственность между независимыми модулями и обеспечить простоту внесения изменений. Если бы логика поиска пути, построения лабиринта и визуализации была сосредоточена в одном классе или реализована процедурно, любое расширение требовало бы переписывания значительной части кода." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "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.14.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/NeklyudovMS/docs/data/task1/performance_plot.png b/NeklyudovMS/docs/data/task1/performance_plot.png new file mode 100644 index 0000000000000000000000000000000000000000..e3eb84c950797815482112b8bc13e7ecb57c3be0 GIT binary patch literal 68485 zcmeFZXH-+``z;zP+Xjj#B2}ssK|nydf^-q-Ado0ky7U^rigXA~KtMX7O7BFaH<8{! zdI?2J2n0gTyZG(>JNtje8TZrua6jBN#vYgrS$Wr6o@YLD&L;s+pD0{9fAc&H2D_xB z_(%f=`>P!WJGuVXS@3_fPrsZ4KSZ77^qe*A&7Iv|IGVv!UpT+Av3ItyG-h%&b9Az_ zw-e+Q<-Nzl^wQb+m6I4BpY4DDfY;v9f{!75@+G**xmSw%PB0iXCG_73i{xGn*a;X+ z>CrnWO`IX*S~F=Y#0YA7r9*)Dj%kOE^A`1p4Lnmsb?H?CB%=d>pGIXNIrzU zh(o>T#fEy`U#|DKo^J$B;3qEF=;=RKCmi`sRoKVGRk^L_dAu^;?W{uQ*{;IRfzST$ z75*dR$tw8Re_iKZKce~9OPJniO0$2zettzU>fi71lVehc=H|cG_5c3{u>W`FKr!>f zMF!S~uVWwA|4fv;Q{%c8&gk=rCz@MVc{SxEnDCFYpQNjG4|dlmy_Ues2dH0}s@Aff z$G{s*j_AJy;CGV2dRA+#c_M%B(5rHWT9rwS7D z2nT$~xAf3W+CT2A*4a(g#tqA!2Cq?{wR3ekaM&T-K@ua9YOS8pb&Z)u&^#)Z57ExI zy}h)Qf?xT=i z&6%>Fs+awlctP=9&q)~N`D)2$ZS8%9yjuxlnrT*TG zAhYguBgges8c~;Cgs`0+2f~~GvEzIv&3sjMJ$!?-mEk-8j^v<^!zcHaEGmd$r}`ty zrVn!QndOYb7&UtmZfHM(aQo>OKkwaTj;*oO_r*?&uA*KGQJ+PT8s)YVJV{CG#?~e# z3mE9Ug;&Pkv*fvOy)!aRfqc0Vac7_#tZ8U*7Z|@wUS3S*@UR~ChG_LC19gX8vP7|! z%4hU=?{E5|-mMBc`2>}-NU5hS6GfuyUth@LTwPSvYh3g7kmTUbUwN!@H24b32*?^& zTQ=*#yolX%$uY}@5BzLKiU(G``U^3m753CbiX)*p8+x98x|O;c`8oQI+Jck^vkS+uQWox%DAc^-DG9bv(ZF; z$i8ud9G*3b#^o?-_T#VnlM`-?=GH$}PkxcBbH{AD@WRC*!TOfaRz?ho{f+lJ}Sq> zX`yp~jcedc6V`F@=N-%5^awBfdK(yYNclu9O?>**^`SG{7e&6w$}p(3&R%YNVa8_G z5i`K&a-}Clw&i8VGkJ+8)y~Uo7C-4UsvOOTR>QyK#9R*_!0SBC1{Y0i6A>|YjPkmD z7k?)9*5F$R5-jlo9;p6obt8=L)?9#u_ukXIyu5VNHWXo?-bj3TFyDVw`qj6*<9&Nh zbz&z;7)NH=GlL|S1a59j)D#w8GyI&0!*)xPP_L6IP>bEkEjb%KX&6*zoS;HYSoPUY z(i_yAnwh03Cl@Aa@T>;qHX2nLY{d2mLI27cuXvZvBjUmG+|6sr`1L*o*Y)vhx%{VK zuy0%0T>M-;GEHCTM=K($Fr9)nxmxJd+5@{YL?8G&oI1Y?pTwb573a#)b}w7dC248* zKM!PNWOk75E)?*(XJs~=jLz$nXoP0Jq!ljkwn8W!N($*2d0^4`Nj>vPB6C-Qkf50V z>PU%7nbpR!?pV2Py7iEqBYxdTNs+6dJ6XCErKZ(i)s-kXb~`{mL=(ASC3Xj=F(ihR zTBlt;l7c;YA1D9|KZ&M9aaHPmPje&^T=dJm<zS>+j60jT>w0b+ix~208 zgG1$){<1N)0T*Ht{YAj6onq!``RC9yZ5wfyXD<))>+kIu5C77`<=SasrfNM(MbZZP zs#mII+1keIkqRHk4`kYhV+UIJ;Hgnsxo}MhiI&#+j@Rb&C2kvVf_Fc^G%*hmrFH?Zl z$?tVCc0>B6kkxG#g=)5?y%VhVtnIJ|=U>hJdDws*?rErA{k@{?t5Rev=K?E0iD`v1 z_QWE{hiHbZtTM0PF=)%t&ShhjDJR4UT9|G{G44cWILvQ%lXVoEb+Fz2A@}zD8@IL5 z{75scrg+EscBKI>?ap=02^;*MKmBa{(Ufd~EyMC=E4i$3#!Z23-(~&NvHlamKP8!Q zTG%&dFzx%>)EA?z`ma`k-Q4rADj9<*c-&WNd9|eFBA8iL(`Y4^ZT+~TSv7$dGpr3| zuRYIi*KE|s(g<2CCl5sBd2BBTw`8M; z=_-t3lD$E(d|gtm13B6mwh6*wap|@-u3L);-{nBzK+jjsX%!WvmSZ}}74bO(-@n5t z1GD`7rKXk&IJ9IiIeP{5g)jTc>ug3#M_%zEwCDBfz27@8kE%*j{aR}%Ac#}I?ve#S zXEZxuWSUQ#lg(SI?{S=f((dZWT%y|~|0p6~SIvj3FN?(b@ZopVaKGH^oYhpVd@G;S z$L{RN%&&pGLj{O1SA_PHtuSey$leT1x%rC zMFHz+YHAAyM=K@~yYcXVNOmxitk9HMklEkMpTmQrd6@MiagZb>WIgz?g8!7Fz6?g` z42;!Uxcp48kIsn~n=?)63i$P{?_`PTu4|)P%UMKI;)hF~Ui(|~mqs=w6KbzI=l%To zMC@&y_r9apYYvdkB6f?)%Y}3KTux|~zEr2V_wvi|@bFSlz)}*Iw%L^L(Y}I%vva>R z1--C@Mn+QVMiO;$Y_IpSC z+ArzEoImL-8t_xVsoHlA|9vd@=;V~jKBLR~8 z=7?Td2)a&WhftpF$=nl?})im10Nk7QS#QD zQgyGa!Q!WU@W?3qlJ+5@Xr_ih{QdoHhA+uSeK(FpfxND?q%0&BOti-_@>Mh|J=ovx z`1Jy@1XGU={VZUHTFt38n4;@Wz+=t}#`2M|w|?q>-?&3k?aQEKfq%+IM4 zXx9Exz=M69LX#akgpDcGyETOrxz(QMXx7{<4N?%>CF!u6^X&9u&VjDuEEDpr7RgAf zJ$>Z4%MP6@Gm3Sow8s;zw>9@OEmpU{Fu+wBM`hVaOiRmj&>o_(9x8~W7k3LZq7vz2 zfxDfC*YnuRObpvkWr-O!q=($f+hQEgW)w~B@&RCky<`+;w^Wz zyT?US`UK?UBzMp#qo@QC`{tETD>qcGlTxla{XhqX#Vf%7N3S($YBmrMyUs|_hk~*zzlJcjt&ZY^fFZs9_l7U z0Bo_UU>2KO{AZeGo=ZdH|Iq zDUGUfQbn8|KpTyPvkLkioz(w>m64>*;cB3<8~&Oiu(bUerJTxeJhd9xE5Tglx+1%h z5-pEv>zGGW9G==S*NUPj@28+b8kkpjtFu>CupfmTAaRJU=DP zHQN%>Ba#OI+^txXY)U7|AD0d*IH#r7eEa7888h35i)LAWA9`?t0ws7eSZtjPOk}Dc zKGs8Cx;p{G)GR#D9W~TJD`NLZ*)bs0v$aGilAS{A8kqEiE8|Hp3OdcD9Cl(mv#H^Zw*LCrD09TPNW&-aY54t+6%XCc8)*aw*!T z1Ypkng|UsD?zOS9K5E9yo%IO?-6(aRgEhC2T8|*!ru#U5#^B;Umau*IsFp(g67#(O zB>N~6g|KC_D#v*UQM2RK*@g#P=a(YV)OQEUZE4YlRmD%jM1SD@ zX@BqNjzM{Q#fu^zMa7R7>GrA$G)9U{$SjvocZUSPbSdhG(up#ILU&+eW3rB0C6+g+ zNOeNYWyf(!n$)xJHc4z?CMkE zF2P%epY-Z2HoH*eOR5iMB&h};bIc6wlXIF+098t$?Kkx5_6j- zl4l}&3#YP-O|BCAG90Fl>JB_D?d|OyYvSu~=g{JdQWj#gLH>3mR&Vwd$$lV@G^nsw zX$ss>CLIx(*L*jQ>Rz@SPWu~WyqcD=mptA;_3rsbS;;@NL?#=ut|1e-kV*U|@*ad8 z^yE}jo__Jiv5!{>#7{-DJ3{Y8uak=O_y(L+&FJZjC6BNo!6xpw{^f4z?q3@ifG*pj z1ugOp0O8%rNGwMA{JBC6yA`PtPrvPs z>4wxbS=E+w%BE}f8>&TON2yajLmdKU%GiUE9(9W7OqJLtGjGMZ9cE>+?6e1%yAq|i zybqsTx~cf~EG}(A#M_GNZxka_xBXLmtBJZHUG~70V3GWmtf^)3%ZmfIDP&<5cY8E< z>>+U|xwqCs5a}dgh}OuM%T;H=8Rk2@upT~4Nt9kEY@8|z2im0hxV*wpH$x@A#2wtkvv*} zsrR=RBaLd@I^u=k=8U988o_x`vDXjk6`K}$|9QyK7B7_h!Yf7Qy>qYkRG74Ijhaw& zE`YdmT?xANMBW7sb%=)1?vX&$dvC4RTr-_{x8XeVAxBTZe)90;82VsHnsm=-s#^!2 zBw{msBX?HHbEoy`K+^=Wv_DT@cB+pYLxy=dU07W`3!rKx932Bdw+j(=F%9zY=w-h^g_L=cBVx1O$ zwylafb=g%IHz|X2FnzEwH)dZyII^>{P(OapcNo370w%I>#IaH9SmAjkd&2N)^ zq%pld;f0d)5=P#dud|FyQdXWAhC(TdOGp(Rud_qMCv*T1v(q&XmVZCG6K+(V@($B=2_BZ>OrG&$)9Nv6W$b*paIyW@|^VTnzuTRap<4jzW zb7X${oj7HdKXlV_VTCK-paK=mO$r{U1RwWYzd4MNdUz=~+e66o0)<+W12mn&qIjerD z^<>**K4hpT@btU9uhJ4qg4apMFlMP;rKYB)IcmB~)R;2Kww<2hyS-9!8s-#n`xK1R z&l4rU9KGZKFnc1??EHMjRjJ2k0_t1B0Aq;D098PS`mDT0tsXypaIVJ_zQcn;oAIT5 z`%f)ru2t4grAA-8xl?s-P%Uj?==*+Bo!5MY90rU2lKD7}&P1B)&n4fJI_hTpfSll~ z!LLS(IxQ$Z__nVXX8UeTQIf)Dxi@3yy+0RQVYXjgA6X(UvchUzOB=zu0>}P!H!Z)2I}8&$76( zD&$u*1AcuXm+>rEPFQN{x2uxC` z{m>KLEOjN79D%T#8_Rtbrrk-B#a6g@cN!7DD9-4z5F?5Cv;WYwfOpXDuaRc&_7jw9Vw2+0>hV|Z}lP!P2+yzt0vZ1H_=klWp{Xf+TzzP2ITbSQp0v10( z?PeMw?zY}qV$t1c6?w-%xa|{v8kks3c)d5xhRJDIEzSQaaeVUpA2P}HTlwkFb4v9| zKFMtdcP6O~XlbjQ77GB9Q>_O8v%s***i{;&>&Tk}xk~TdxLa$kaVf5kSIvWxb_-s1 z(;OecYb3TgSqWE;;o$`PEB4L%z}jj3f9oi}Rnvzb#a*NkXa!VqhGT{@U@){tDtio8 zS69Y4Tm7 zyZ?ZrZEtT+F@Mx09U{w07B+(X7jLvha)dojy4SN>Uv58j3sg{b&MW=;D}&aTu|?UZ z<9vux(DsxZwEg!0FN@XsXu9NjM)eETQ1~Rk$2D$O4;U zp|u{{fny)}%m4{n>^Psi=@`u7PocEX8OM6}?p-(mMB4{DfF7RjNxO{xW7pKka2|Ev z*bP9BM!8jTrzC#6&Mnwe_)e<#gkQaCQ&9=aDPR^#`U|@MdFa05;~!2n)*2As~Qh0YvY`2v`0D~ z8(OK?C#fP>tmbxbybxz27d=YH5_v zs94F3-97~k1DS@&tYsZNTjq8l8bn?iX`j5$;%-llM2Ibo3=oC?-%G3E)n+lS9{<-|laJ0XRl`Ad(2@qmg zSs5H&PgjjFbaHTr2@h}C+W+>NfU7RG>}%gLQ^9$;QBZ7dZ->P?{PT9`C)0b5_Pqmt z_N4nUF88V?dib4*0arO@Y%j(Mm_^+b%2BA2^fmxw(X1^*ul@H@oDL8mBj0PCsBy~x zmFUdx=Zt9Mpj>Osy747?>AvfAy7}@^V{cCKwQVnUXFN|~-UM2}zphU)&osV3Vp8q? zg`I=Kmas^$D`?7bK+~aHT{G)Ws++-Lt@WnTyhKKdkh#Hoj_#?!|3mWJ>;J zP~xGuv~yb5jl|6W3^um5;Ev|fi2_AV>+f5#A-mlG7J}1fxV6whjV`1RbBTJw=-j)} zmvM>My0y^7ovTZ-9d5C0RNR#GF+>IRqcv4VzdD`pTgv9r<3rRxUVQ;FanZ+#6UVFS z*Qjtv{*A729f&&`Hl@3BZC3$wc)PQKk1Mqq(SV3kxAk$r=Ek(+ud*uwSW|LPTwXqS zPWXyhYxwt)16|UQ;Rq7Yr`pZTKUg}PRO5O${<*fd=g)QC|%-yF(zb~{(%g$E16&G$B8S9 zq1p0yDyFXeb|E&t0+VDToravN0 zp?o>CKH&&RQ;*$MePfDC4=7_n{N;T5?TOVu9_Q}vF2SuWKcOO<=M?PRyGJw^)C)eR z!R@AsG(j?q8E!Zc9t;VGq{-HpI|=={2D&7vX>)LvH~oj{za@Z&f-${7FUNq7S~wC= zgV&|{NyD~H@R1y9ZD`G`j70@W=iz#jZ~<;;^Cn}fQjBmkRyN0=z`>SiF;8xC(!!5$p4s5hTX zf0FpD*t9Km3Q^}N1lEKpuG)1i9-cGBv4RJ;`sf8V&df(+tdi0Y@}GE{61rDp+&p<`u#j=o@#KR`!*rys070aFa~n|nQ+2yOXvE?Z*?n4%4k(orKN=F0Wn`*VOq zcl`6~R+R(sgK0;SDpwRAUo@FEN=<5+d!ia2o+$37q`bW~ucBXJSNHhSpTtUGYc4cv zbbr2qLT&9}d#P&lKAifg=~28!%KwSXH^KAH&=iRuKRAla z*bPcLC;>{d=TE=j%$3M_^PK}r>gniK&Dv&~P@J0bfM8IF+iK7{ckUd&jjnzl5O`7Q zEDC`j9;a*Bu_&}d5fENiO<2T`;B09V6KtH-9^0AD*rSNxBde(U;-YQQxw>WmzK)dJ z8i0cUg7QN)|GmUv$@Swj$12^p-nf1q8jup;^1r_9%X~8MozNH%3F#}$wz_c>Tv)H6 zf(hfuHysZqffz-gxN*C!sUCTdjex;+t8!HSX~;|Q=r|WSgpaa3nGgK zP%t2I^7NTAZT*&{AlE6NfOLRE58sP?ZlpB^1=D1oUR_9)Cqt4i?Zd<9q;5NzccZrEI}#+;r4M$O>fy0s zE>@enlV2*(NM@_4`b4-iK)R7g`7$Jsq2-fRoF9j9S9hla1z_7F%177LO{1!AlU zpr+?0>%5As2699g6w>4`ne}H!ID!Bq>M-*TAngZ%RGd7j3Bp%^?*Y<%ZKjGE^6JH0 zR&JB;?xGCcJ%b0Sp){lz_i-Xk{&>5lzZ;gc0;d|rO3w<7$wT8B0x>0GmCUaC(r*v5 zEWLtycSW$0^5h)0W5`o34^9wR7K0=9J5|(%f%STxZTxg+qk2tUq~2d$eymkO(5v^VE_jJv&*( z<&_l`6^$vNDqe}I$ZG}~7R*odaBL+9+|6qxVt*RO~EMDJGNE79olxJ z{ije_@;Z;+-O;Vk9vY!`RRQzP+v^Mr{7K#6x8CBo%Xdj7LrW5;_z;7O)xU?{Z!M`W ziN?#CP2mBI06A0Hx7>EDJOHN$Mhiu7g};~e7ner%`E{#@9dxqtBpDi1X4)(ridNu9fPt6-9mVP=m%f^#|S@n z_s{_~D5WsXGrNlX{WyWc6E}{-+EozN^b&;aV;Cf>RkqCw1nkD$C1cT5TIi;euCA0+ zbT+QS<>$G44~P`|#=}qP-%VkB5nxx}!Vq_BZhZ|^?1~jLU%gKZ%=W}t6&vphq`5Q& zQO8oUDKBZDSmZ0^R&t--8(E*0kd$O)oht%lY?=OIi4XB?+&vHFbllolMUe1wMnUt> zpoks$;{-C8DUnd7k)eDItx;7B%pXk6CgS&pRs6}tbaBB;T=ixy)k% zBmpR=yjE1hZ|ug(Zj4`o!Zr{6|9Bm9#|27eJO&kZkpP1PgoK1#r28d3iqt;qax6_@ z@NjLVSl&cBi5t(_dkg{H>i_elZU&<^r=r}MO?$wYao1fWCl4*{YHwGz8bZ_C9su=G z8HkRi3wipKH>g<8EjNeI7Ta$~5hn)+2lIp(7}g0VTb(+G-5DUy80w@ko^%Wbm^fKn zNfgHuPYvZ0BH6`XBje!IL|j3T#{wWOH=30a6qIMM$aak@N~E(#l#r`VASQE@0tYs= zlv+Y)>s&_KKyeTRs7X3e$GQCOS-?<<31ZBO;4@;HfLU1`Tw!yyx zoOCn74kKHNSsO}@OD8XTDwi^jAFWwa-k+x~+a2Z!ij31YZv8#br~io`D<3Chk3pj| zKaR4ocTr_+xG1tSNm7%5-{6q+@<}fl02}_+NU=ra7Vr{G)_S-+Wu&5FO_Q%y0<;S& zkX}7~25_{(jf78JznoocbEZh;OZfYuVc>+cGy3wxfSA_7z7bMvjkkmNG6=ImY90`i zb5z*nn?}Vj7jNEcTy>1GpDh90?g8*A;ep_QIt$oo5SUCs!QuF=g`;`bDzCzRDgx-q zEeCpFpNBhNuJMOZDC~iT!YV`HF`x;0M58Bhjdd_v-vFROX5ODaH8LO5pmn;GyAhte zOb^J0F{DlZ(`1MUxTIHmPg;xVCW@`tW@Jl5Y*P9F-vQV<7j{CsG%2`bd(ZJ*!e>dh zCt@zEOl4MsD3G(;0NXe>2FwnjJ*TmOK&9s~GM6A(c`xt2&~5O#=1z7N9s|Hv>mjgF zfZW)*V$x0_-3l<%j6)Qdcg4Vu69E7h97mk15LA!KC@wD&+~8wHrRN(6FPjn1{#0L& z1Qw$G-GstR4-?N{k8poh{_>VI@tzUTmf7E)z4T;t8fG5UJ;eskztE(Q;Ecew`(E|> z3pOdhaEi(pKL^lx+cgk=0ft2h9~a7!`?p*b9IqoVY9OU5tdi@wt|p1WJT2gm(Lty7$%S73cjeRU**BcmrFCu5a>D&_#8n0nF5v(D5E`~9szIg z8~Pjno`UwfyQWsu2}-{-6aD4kqPLLIP^aKf^TS2@m|Tx_ej;*mG)yNR z$4kgz!0%wJw#S?D!PWyP?@v+zbK}3R|F2kXFZ{~URsm7VF&KM1Xx{%lVSaO913q}< zIM)iu5ek%xbzS3Bw=Qt4vK;KL#~iy>xwIdzPM@&Pcg=sc)%54Zhh(Sub~d1NM8A1| zo_z)4q>TZ!!ATD$^S7!Qu#tVZM9(blW*6({WHI;aA!8hH8O;IiY!IohuiplU_z_Y! zT$J&Z4xgmt1e@3Hs(QInqF5PF_*8`Lw+8v+H;PyUOq$g+YTY+qhRx5+@NmcQMQU;o zan=A0&dl|Ho2v&UWz3gvD*W{}wl>DdpHK;ycuzIrVJ_|2R9#ESO>`KGuMi@CZSZ8qD{ zd&Rb6yNwJ0{rio4oOp2#0?78vz#dWTyljj%M57F=9JPh*cCL$yi$iWX85Z*L?YIC;ZSFBSe0$OK|45R!J{CZDw}tGz6Ic4 z&zP|N2oH#lK+!0eS)F6G9dik1Q3!n`rc(%)bdmW9vbO2sPou4!Wlgj}MJUgq%j;k| zQRRg$#Pd?pYvMr~og46A;r0>L&PpfWzUe$#y)6Cr$eH$;)z6*K9!|r zzxj$WpSz>fc4#uM9;94nRB-Ijv*m-fEP&K6)cLI5P+K0^W^r(1yaOVJuvH)0gbWzh zKmY_n91F1J{K5`YiE-pYYP;%;X?2n(9lr+-DnYexaCOk zdkK%NN51>C{6%J~m78KGGF7oUC~#)dT)A#3&`7Ua%c6pdUDw2nBIMa7?^*T#%2ov| zJlK<^#jkpp!7qWs8lL&&AXy4*3~2$ZU@K4wlYS`a7a70Tx4rBO7F`KC4jy39ujf8| zOQ<$|323LdUCgrjx*Mo%^uIoTon#_%_@?`_$EyZJA&C7+oyqthI!Q;x?hUNdZ$|JJ zNj}vxE^NwC;mf21c7KZfR^X|g`_g?P4lp=Aqcbi*bm(i*+}_E#@T^R$<>_|4ogPMK zwA|Lj(boxX1^@kOrS4glaz*|65MnVwVq-XT%~tyDM?RN}LVP9hvZ6q+j2Hzhly-9% zEq6k#$jybe2|(;shV1pueeSr@-4vBw?%$o9SDrvQ;99m0T-&VdD^s&LUv9as6M2Im zxAJNvs1bZ@_CBZHq=vF8L>Cl5i+c+8I9DU1SPujoKu*t9CL_|jis7&W zk@qZnTY1g(?*o@YSY9w3N*6#E+H8s7gbJAmk zTMx$HaB@%h)RG5WZCrp2MK$<`wN^QuFfV&}$mGi5s(YL*nb0OHY1A?yy@jHgX4k+ejF6@X^wtdWny8PQqVyg%UnYey7u5$|7 zK^}j8KP;UE;#V{r=r;n*PLB?m|1gyeo=3r0w;47{N+9Tsu==O}C zh_Bzis&=_7FHiGI6ZfRi`njPDx{of=R=4i1iG%Kix{I&T@mF0(dYiWP7f+eZ%G)D1 zJ$A>d6c50q+&+Q4T=Ev-gXedSwTh1ju&*Zu|J^6el9svg}(6a z8h4CRM&LD^oS)|w+h;D)@~qR-^(l;fDQUPUskcmpdcRW59%7V~EP-^BL-Ha&f1Z+- zHsQFseozW+yKBd^l%HjJdATRrm|FAA+qbyhpFf2c>TPU7Mjwsn4)e=~*_-Ilj{Oxa z@M8=Zlv|cMa6@Bg&Ll0FE>PpA(K!M1njw!{5i8%vZfNr-vCKdmOO4Di38zG_$@krO zzB5jf&wjG@+H5`7RpR5AP=X)FWCTP02)!;BCnO>?H+ zUa-7k{~|oA{Re}TvmQn*QY@sW91wMKH%msRCMGly-nCM0j>=C#BggXLLk`GkusU8Q z4zb>_%PhwDO4-$oGnUTr^mKG za^y`fjdd^G4^yq+w~EDKTr*4U1~ghY#>(x7v|k#VU}IF-5uor7)t26)DDnb~s~Y?` z!~)NbA}psfEj||aGf^DSNGmt+z8iHpo}eZ`uvZlR#eM5$J>rp%j}QCeG!eUjNwe7& z2F_=8S^tZJaesh;A<%VdIC#xg>g`7@b8lH{YDq?H{#b?CMm>@}S!{Wxt?zc!A#cQk9qw z!;-ruEUsaIF@%NJ-o;V!41(Gg2fQhU{Oh^J1=>{-^Mm=nT#H_qnB>P&^TF?lf79hP zsyB5!m{&=er^(-5469vp{L&^I`(yMSo?cgq@%{tA*{~%0jH+2IDR2mzcqMdyfy_78 zdLmd9GDvA3g7B8%gF_is?*de&>P$pR88^^pVmX-e&5;xyU*R|B^y7w*zk3t+=q z;jzbUh^+=q7h810t9*#nyeH6fVoNN*_7k*uiS zl|DA3fsnUCKvF%pXQ>esQWo-a3G&Uw%<*z@8$N6WCrkJ%smU~=^ZxEgF5zdZ#oMS}}>4AOy^JF~LF1-zB9 zfH734vd@jVgL6CxrMIWzAv<#hYX;0gU85wx(Ro^eMlr`4qu0N1-*pQfO`2O+SE~*a z{?yO@&`pz92F*B)6AgWNM3duFuEiwz^4Ie;mt-U%Aee5M9axbfryCTOTvTt040deP zColn;R%BEfglLq=hPZlC5ZdH6z#o94Nj{nlD|WM=6Nt)LHPt#%Q~k{yWLjgV`9L$M zUrWHD*OXrYZ^x({K*?r0Ub$J6R0!x=CjKim7|G+9`JjD%W1}!O)Qn!$&dvFvk?%}n zz^8+)3ll9pMK)B(=#c(c#PFteuPi7&S(>b-Z4cEBb zKuJ`6T{llpeYq#Crq+931GE_s{p`0G#0I%?~+2<udS4)+%kj(dNul#Di-+t_c@d@6RG5UT@lBJhQg zyMFiY-@h*8e2f=zita~8t{1ifVWwjscgXqNDDXq@n&kX+`StsuBj_0suvq6iCm;{% zpGuk4BXC%*Lee->J^lUPY1|^&mfqoo7(fAN75+TkHXbe?jp!Gj6F)QKMmh(y`ReLIvgAjp2K}u|GTEEyCfQf`b8{$! zg@vnALv!?Ar@sa>cDaTFs#U+zDd7vRT<+HTK=6D0b`In!0q54|%Tt(S-Uw=SKm?m^ zGGeenwIfaoP&d%jo_n9~p%UN3gaWq8iA7_c4clK}yXP^mG60dBMhk^bixk1TYy0XH zMnCV~zONTcg-jIlcQ9#D&J3mrNxHe*Q?a1fEXCU+3^GVQV4St`4>dYC5w zxq^<7hbR#Q99fi;#xvB@Ge3v~itsbri*4^VFp<28;wldw_%TGDf2Cd3qb9wU z#U~8UO6vSNM2)F&9&{_W8A%6}At4})Q~Gf0fgVN zyXW=EGpt4EJm-olh?~5g{gDDI%k((V1c|o0`DuG2Ls>1}>ovd+;h;vuh#KSH$%2|z zkq6kXBSHJEQZ$#gDZU`Fn(Iw|V!l?6p1R$5<*m2=7llR<+RC@#wUu*Sv3wec^>qdf zP>36yYkpDl_NWF?Y^s#_?iDCzB_vxOS#7t>u=Rdz2OY(FsC zet-E^0SIRQj5a0&P>QvX?3q7W21ISfWhTXFVXYJC)qaNM-c^SLtPH(j%X^>#U}s$b z?20OU3b(Mx&Eg}cyU*my1Gg&OC@`wYQ0g-$ET6m9pL3xH5Y*Ux*Mawi)#3N%2iL@V z^E@ulh&sN5Bz7QF<)|3tbRL4pr(}4Jyq;P5XvZmUw9(bZoTDd3kw(<}Vj__eJWVgh}S=M2QOO4d~6GZI8+c zBF9ZF090W%{X=dGpQCM#OG%>pbJyvK0f`&r(06Y-XmrL(% zL1ut5xVK1_%)!+W_!ksr%3Sk7W1@b`l}x}eD{wS;_f`}Zyh_RD8}KFUTa1)iIz^di zA-?5eYI2mHXdzj^3Bu6)y=!9b{M&hv;#4|l|C?@Jifiu>Fr~NyK7~s4qdV_4sBc2_ z7U=W?4b*ShIF;H>-tNzAy9EF-!C_EWc@B^@jSMIKDuP>J?*UPIOX>;q7a$e`q!(U# zrKSN`mK4c19W)qdjXCOll7TW5HcbB&_@G>Bcc7lM|6Z*8plk16*EeP$aQ*8wEGS&K z2ncg_s}nV9HZ~U&HKL+gAfcGGG@Xu-W4;JtThHC$Y-v&Q0L~p&7eJi;>+S#dFBI_8 z*I?T{{;N-5_~0LkQXi*IFil6?HaU?b?Q7=_G|~7+^cVc*xK&3>*?kM4Yy%D*6EB3^ zFO!&$LR5jucL|{0c5md^ZDyMUt(9>&Tsz58o|>zQeuHCHWURmtn+@R zT!;7;Km$^G-3ErTmjD1wUWb_Ca}7iIO88)ozNSWo@fH=VD9gtU5-Kp#*LTIwfUzFs zHU&|w4f7*75%snG`I-ixPlkz%f&tZX>(&-m5!qQLCCykoji4C{NN6iljMEr3kPZ$3 z@BN1zLZXW9z(1uJa&w>wnBzQs`ej`=MpytM2i?O-S1_kO3cCVd2wGWyOG%zc?txp$ z*rWTS1PD04CMNY}89HEQ1^49yZU51LKO~%i72&#p6fxHdcyF+b$Ci~!h^T&WSmVBo z;xXJwa9-=x_wC7t!!8>@H|15wXoBZ_3#>K8-c8E;_!+sxL@N^$`k0dQFn$j<&<;ol zxPglTzORqI(7aqco)=ZN%*kpG6)s&g&pcg+^6simfFvudt+CF_4d<-#A7@PXSH-9z zCdfhwJfh3GpfP~W_Sw)DFjgrtvlZO;ak;vKb$1e@66hmLe>MGMYpF+; zc;*kVMa+YE5&>*qf?0q~dpe248+qU-&TD|uksj|O_3|r^QFZ4WKQI?&sLN72I66|2 zk$JVn31*E0Q8AQ3lKsNWj{H)~Z zO4tUFWUhMMfVTP%U_WO9g+xqyG*=s>b^(T<2y{t=(u;otKkivi%7E^vmpTZp*JcAN zn2eVZ%nBBwS(MR@UwPq!A?Qtq< za&!NiD!x&s-ggZE0Dhgt{n;JM>Iu*yKmRMGLF{$b^Y3pUTL&>-)Vkc=Gc=-62GT5G ztc;Bt;D-`or4iW6pr~s3``ZaIrRJ6v1*?Gq7NqpPR=kie0yHl}U!!2^$U~{|Uji3x zlvS{v`#Q3uGw~n@bSym{pHNWv7kRtVpU(#r`snhtQI+Jd17+al1d5*}ie2?)n(&al zVJu+hTE9G$P4_uvp>kqJlE2Z^!|>ZgYBSUwa>6BaG$d?;+OBZ zVEg$G4F3r{N_uf1m=Lr=A}E=6cAB0{VQy zIn?Axnnb(JTbzUzql>_xSr;saS+>A|Lpc1jVPn*?>7a={8<>J1mFeNeduG4TSAc zP8Mn%RV5at2jzDJfbI&uHKE}CeGrjAXwyP#=!0)2m;;rl<9Ih;ud6nVJm`9-GeH2F zvo9L4yD?=S^(QqOH8(k#;CylIAClA4DlXB;qD zxJyD?1G<=Aq(@V6{VjSJaUHcs=N3DpRSb`eD7A#rH-aDWLiV>H+90>E$V8&?`}gmw zCO}qEJ=$X_ZLAS%2L5{7)hYm-qUw>-F*^CrR#58z;M8vJLuJ;+$jJDcdI-`{w8tP#ro$3TG(`}HZZB~}_nM#kk~bV-Uwlnv~$UlDXChmJhg*VzWpZX%Z{=-jqnr zNDkl{e^xiI59xrL4WOTi@9o>dPvZ=9ba}C^uI2oAGZX87YHDxVlF?zP!L=<(vIfW{ z@)%uB$$z#f*a&gA({d{Q*`a2NsN+`hwb8O@NHkANOPf|2UJ9lql}!_Ym*(p1QH|S1 zPvOu6h(Bj3Xt)6Tt_VUPE|%i;>(@p1q1H*J7p85W_4x++6*46}sj8(^2J`swz*fA2 zeE+T)tIx6%Et)C(g5PKGD{-a)65c_R&K1xeWd_7h^NO)*v&c3a;Im=?1JgJSz6<6* zS5Y)@;es#|6dfJ?S=#qu=)u0+==yw_4j*mxeU8210(c!4B*$!k)rkGw0(oaH13{Mf z=vk>d0>W5C!X-tJWBIR)FWCqe5jnc~;?;7P9b$~OI{&SB` zK<^l<0N3GTyKX>95F5xSjMuT#4NC{@RL|-b9=@w*XzFLro9TKBo<;*Zm~Yznkq=iX zefTxOu-2VlXALXzDpWh;A3N}aA4(C|%=)9`m4WIJIR?sPz=iTUW8U@Gd5K60MFF;_ z%6VDi4I?8M=Us(8s+7UOeO0>(V9M?2h&4%4zIXRF&|IRBa-U-E-M!nIC;U2=PsPyD z)fENp3czKi>lR8mF8!LmzXsg`x`6lBR4$I^g<9-~cke!p9|8Xkfk(fDeW|it?0)OF z6Dek6ExtsTyis}Fj^*@^_w&Fn?jRrq-pTYCgTcVX{_VClUhm*@W>jb?R^I`9DZ=MP z3+O|ON>@$Lfk0Dn2q_?vQWtbCu?t#shJzT;W^1E`o zF?Q%%Siol}gN}%h@(i_PxS`=^7v|1|E`y6$ZCn$`b69ljzbpDWHeS#i$GyGS6@8JW z7i!pU1!U4pI^w@$LNQ-8W03Mpk6p>E=8O~cFYw*_{qRjN2LS5DFQ-p(>V5r^_pI(2 zsFND2!w8o?tJY_;gJ|lv_a&1dUc~qHaSxh&kxQ~vT@&bA00t3m(6{gbCt2+lNk3Kr zwd~R2TtJn-k1fQofv~mJB{Itf65z?uC{5=Zq+627dPBynFX4Uw-~}!nmES zZGLPlpZ_{_a)0cJ?L`tZIH{4qtffLaIyDbSs!bn5Faf`9RTITjt%eHNfITl_qQ(ZmuN*0fqDbUP#i3yFP{_WV80D7^f2_*dyCWdbN*k-h0Ue zwBrcy^lb$bH9Pz{y1AKI`fF3Zeg#_F)dRUC;aWbuFMe4$$3nV6TIt>b(yhb={g$u^|Q}HehZt zD(xO8;;NQHSXapsyY$^H18Vk4Yi?Fz-K@X=GrUra;4$pT6{Y&7^$o^!&BRAkf_KDS zR;RP$8v%<3ODKr2(q#_RNglZ7B%lSCdN)8h3c{vjXf+=sp>nI9srYzaN!(5(Y20$_R|njcnOel|R})5)g9n}I^vt^IQ8ov>O@@GE5@$ViuqN1Pomg4- zYT;*PWv#eY#|_3fJUyuyahDPxP2GFZc`$P;kAn&qv?w{pnXhU9RkymClh>Ld=94_3 zf?2PY%c!1i$LKZCl9Rz*WJLuE5rAqI*B1;Tf3pt8R2xDYZS%y5FvF#eTaG*2T@4YO zE63$OwEY(OriLGA+9iXTYUk9p{tErr_TV4WGuW5LIYB5(Bc=!!*s!}3I^iIZ>{5EL zxw(0&a}5#}2lFA8bCpyyj0WT*Q)evtUbHBcILx&7jFRSkKK#8e(t@D3@dbe*Z@O+- zIIMUHhxuM+VEB+}i)iaU(hYN>1w~)WE+Qg9cTjH7ZR709%EeUw)~Wl7o9?AAp3!Oo z7s_a58h2!?*pHkU#CP~Lzf=6}V;{nvKE1v%ovF-FyFRi^J2q2dYwgte?T0@vz6|2R z@9wF~Av)D*_wR0LR(7`iJ%!5vn*XL1!KbbE#x;{l?a><0488J(03HbbuG$O~ziOV~ z`}gbHXORM_xIFILPY<+9`rp9p?!gPM3tx}=Gz(BI=vRLY=Ish2Fs%Lx#eiDccjr&! zBmUO|y7zl*KYmJOzr4xwfBkpm`v1S*K%6_`-!p4N=#vGDdF*Pe85tST8=SvjNDy-! z1N*d!4FWcbp9T<%)S965W+>$DNk3AvN`Qi#cbiA&;za37!iER9Ne#n|O8>{vrM zxS!o8uhjrL(VhpIklU32<=FXzhd9|wWDy$ioN%+)4u8FGbOwn2oGeGyfZXuH8#N7~ z;yZZgP%u<{Z)=X=lb{GQUPIiVg+(p)3YV2o;IX}hmhRZA`<|_3>YNK&`La;4A4^vN zlQzT7Mv7tRJwt8+Leh6O)9t264~*|}mVr)`JdGT+!K-a&;C0ap-FYeHFh6*1zEb<* z$=yIhU}Y1d(YNs7gK}oFPT13@N>wX zrN?B$s-W}}c9>>^GO887wLHa6GnZ&@6bVIKbVo#LswZ;j0O^G6kdkN^Wd4&Y2DMJI zPyF(IC(q~jFHg@h^MOKL#+R4dE8RulqCTfOZzsLEyrFULK9;=D zsQ!uap_44jHSy=r9r)=h?@l@ew3{YrmBZuw^&q2djN;SY-rh-;^qU4wG`WF3U_@b1 zlDq|`fg$KC605?Y0>uCPgg;wb2IV=u=?|ztEQmb<Re>?BTwIklxJUrOW$pgt4{ z=Uz+r0JBF{{H1fG@T|vXxy#BnQ|t0omXdLZ=Zh^;6~4iSp@C3#gKCT`ju9Onl=Af82n;*6EJFA|&=_3y)kqN0mu6l@{59kQZ z$OhU^QlRgPzM@xMXhlVZ-X_f&U&%n1fSo(=SRmUxV@In$G@`t0uOn>F4S$_khYcUu z)VN%{B69pmy)R&_<=<|ujql6`~y7UF_WgA~#6FcjQny2RO#GQh&G%ZxubV$CCKEa( zpw~rT(HJ7)7&`GUc;j!c{r{w^in{EkZ7F_x70n}igv8Um6b$!sW22-rs{>v zit+V@5f@X~(QVv-TK-!`9?G(w{Qfn5*0ulflPEGNWWJj8Tu`uEs&{U>_Zp{wOYQmC z_nm+s0`>oD!EM#pG!o^_2+Gxc0tT`9AN zzIG;SoEj)0kItV3a`_VKv$1!jK+!M2rk=#iRr%Z zLF^zALVf>*l@-3Md1x!nbXTfMx(W5CVZl49PTymP9R&=lN(xT!wB$0U{MyoEhMUNH zTfnT-yn;%o{vFe+6j<4j@6NnQkrwT!u2MXf^Ho z`ElyR6KRXx|4^hbz*g3ZBM|APGbGqf{AdV7NEGbg?azon0$j%h0js4>G*Qx>9&{*= z?Xu2X@~qEL^=JT(E*1m;1G!7qYq&ZYZpo$w^cdgEq1(XnwJUL&!WFzbUqDkRMSkNV zqgNUWheKf@klU`BwikN=ZU931FLg+N2@b-`lpQy~*FAl}Hxl)R zs^8f9>QuO>LcyCXKh=tQL%f#5fXvWxIcN3cPe>QdT|hw$3Ez{!UKLq!AtuO%(V$z1 z1u)o>Z@j4iQx-SfjTDelDAp^7-H9sYkATvsdN>50=)3f?MivHZ&?xvrpvYcsk}7+J zQjl@=3elf_&IKHy-It_Wb<}sGyDt&_dSsaEi4Q@IDCy^_xfYNu1@nLUhhUnUfs@DX zzdXL{L3&}=<0lP=^O6!@KoRtm{vTWD|0l13cqkHifeJPVb~3q_B|J8hPmzIx^5R4@ zExrUsShcJUDoF4qXnE1?pw9ieJqk|gc0Eabvw3W zjm)va4uSKyEwyrioCqI6Tm*38TPxkm$ZOT1)f_3bWa9pdJ)3| z5ldo50$O;9w}t}aU$fLM7g_zll4hY4aPf(ajkN=BznIwAB+aFhHXt<4-@JN|EmMua zF5z=L=rGxC*bz$p>8jAd3KyCCn=8p1TkK=NdXu!ccCS7wk|)WujlrdFoIRRey-BAP zXdbXwz`OD&N@)}MQD+Lw#cDQnSXDEa#>N!g@f4wUa&TpX=xr;M}w#dL6mH5O{`tP*tmrKC( zwM6rTDLOjzlF|284E4(7UOC}!2?O-b%l8f?GeB{_nNx~bmZNRB_k|@r_?YnD z?gBWWf(q#36-vcmc`)V8%d(K7ocKu60#PwQXbkna9Lhr%7dslrYr6pFV!oCZxDH~y znI79;@Et+{R2yL!f_1zo*XkGKLVELR>N5Aj{r&D7n%pKWM#J~--Ls2a_oM8TLFBGE zvl((?3b2>tnBU!ex0UuF!fS2$4w)H#yHtJ~8YA|R>nr$jq}8>uc7U@L-_H0aCieSk zp_jfpu$-bn@tuhP5YBqV1+1nA#Baf*|(!p_<{ zsOSWypYO)R@t}Fg2{O`eax#02G5jE8LbI$aLB4@jH%7qQX{J z8Bl{unq_8ocBOT#7+W`6S@{g#5XwwytAF&_*7_z*Kmv9oXw&9jBD-}VsiV-MQ7+8o zRM8q#ThD#n%-ov$TJ$GZo~9Ff9|gJ2i{!VLBa7Kcu?V-9k6sn)sWk9J&aPSfe|;EA zb-4xCz3XP7GlDpAl(zc(g_0HtGpsXDp4Ap{W%^lAU31R$vUXE%6a_8+-b=hST#fC8 ze7Vc*Yhhji)9EcmHxwhC!srs~t1_$5ettT=E?6jEFXKsPs8qo3T_)fXHeQ)$=v9dg zd|$Pib!@YqN+tTa;d<7MtqMOj&DYH<)-P(gCv?Ilj4 zyoPfjFp%WQpa1-?dtca!6XbQmy*%*zrIIndkQl$;_%+Mvhd?{Y>orejzt^UP7{<>_$+?fi0!k$rh@7|9{%U#+`%BUD6 zsD{aJ{`T&qN1!t(r}pshsIX(h-?Ax7G??6kAFb+-(4Q3b_cuzM%rsA`+1 zXnu=Oi){tE!m4lXxW_--aRS3|qC7O0ET<*-(Cw)5{0>Wh9`ItIqaa<+a@pTm_!-EW z>%jdd33R!88V`%x_2F)E$jaM z;~YBD>QN#`*hUxfkFh#N9wl64jogD+h7vY?6PCIEgJVOSUFe7jj#F zTxXDeIqqW@vrETAPNu z<=*3ik^xo=Sq@Ud#>*c{<=tu(V^{okp43;ZO}6Mp=n}wvbI|3N4EgOUFH+e4e-aga z#Jy;(`|13Y0%*m;50WxYsmn7c#3kq}D|<2O`#E%R+JeFH)!NR#U~zf#bi*}K_svRW zAZ+cu#1{jh2Q&=90)`vNf@kK`+EnW!j3IL2W|^AfznQd7BevUVH2me+LBI8@SZfNz zq@68y7$Q*EuBy{cngxgUAKi2m!oB7@GE?nl-d~LHB0lJx)KCRY3r*nLk{&Sm&LS*# zd2b7+RXMl;Pv_U#9WKv$kZ>HZXuf#`e}iJ6fByf9!1L=N{xb>d>-YaR%m42hasbhk z+kEoZo)X(Kn2K@^228vil_90~*xk;ZLv)}TCzrRo9;@{mck^AQrlvT6$rX^N0Q{n4 zFxk&@4k?Neag}rnpbnzo!Jy8Flq(x-zM8piV5%^M)o+MkKf#!~pJA;42sw~OD_8nc ziIU@O;lAG;lR;wAFE1;Of0urC%Ft7bIQ$CEAf}z=4^c&#RSBa*nE#eABd6(PN334! zQ;fUmE=CTLH-F`5)VBSvbLJrFT3Gg}if_RWDH8Z2a&e;WEKn8)J;ZSY0xJ?(Wy$+5 z05cWjj;qr6`JpnCRTBj8G=Qk#%YoN*zx?AT5L^ZX1lY~AYl7$|sS5>$^ZiozdTxup z0)b3UB_-lmx)EseZ(<$bV*kj8Rqy?BhK)GU0w(^dBys^ocV zAWBJ`LRa=W$5&Um(~+{@aCp8jBrvpgVlAOKvyFWLkzv~elh0$!Ued$?0SqNZh&y=HqJtPbCeWMQv67Ws>(|?xB z$F7RG!v>34mW)R`!mrdUpV*OX!GHI0xc=zxgoqrLH-g=La+k?#DcC)2FAJ| zt3=6zoZe9<>%ik5y!n(Nl||8FdGp78hbGe_L4$1AHvTSXQ)gr>ImA#$N5^hhUeF|U z|FaQogy2?G0p}OG>_+YCi3SUMg#{NHcJt|V*RcK*TP9lZ-a#dQFzAtQbQgLsH-dLP z?_KFHm#SFfo=!(KHd?2Gw7ek}c0)$8l$~ImrVD0-uWP6`G=RZpvox*{`yhnRObw)T zf3&PR4%VGRQlt}iKyk+Dd6YIB%pAsG8G!%{KKGj@Q(b6wcDCOB1NvMg7X$@0IA>?f z4dxnZIuTLgAvMqPI=^v2?h!d(ukLZs$CZ*OT$^n_uEg?e9B!CopKK`88GwqpwH!AV zji#0s7@;T(B5y_+D55NXK1ZV9bhbzyywSCTi~%$cbDD$s%o^Q|>PX!6&jc)ARdqfX z0j!n)P$JEm*u~VQ^pO`dL{;C~Ox-w)2}4XC7%?#lJzQY+$!u&d{ee`}I6~nSom2eb zkW+Hif(M#>4yR7>bHt*~LhOsc?eE%)Rim(+pnGt2b+#`x)!1eI<1;YR*AU%)UY4b^ zkqXCrY5y;i5#4Vf{EL%FeMMJ-(>-s5siQWpjq7;hGd!)R)33Jr#I%w_>M8H1`H0Uh zuP^~2=Y$o_-m&|lV|V?iUp6VfHDqTxP#T8l)QzgRKWwvD-obI5HhTKa8osv9d+B?Q zia*m|9F<^b+U(zXhJvDYdIhb5XDZC}VjM zd>Qjsp~Ag82D0PNpL5r6`uoQFISWVd+=!s8Fo;vUg)g)~G(4odQoQEH1l+q}(EB5n zD8Sd`otcK=h-6a#Ta%(<(5CtLbVkJB;GiU4;Ni-L-mG*lF3%z^k3&fxm%u^1Yla^_ z^0|CaTiFlgC$OClNnHOW6ZP3@V((zYy%%PBcp`yC;s!3xZXmZn+aWB;%nUR*>MxVQ zE&U%+b)F;@Fo!04ARqEy@L1h429KQ;n7h%YRk>kY?zUKGB5W;5@fom{3+D(yv=YA? zkS%jt5C2RdRIhM!eVx2ez_e8ZIRO4J(cA!yKEGZt6H+g=+Z6{_y|W&K3fZI7!dYFJ z590s$X%oK`#j{41$WQC`UIy%d^qb;DOkU_wgArlG=1%zruBL7RwF*MPv*GjQB?``k znp*~VWXP5$&$Uaj2j_tU9-1u3Nyotah1==vl|;ad>gkdDP5H*6#B{^Jz$N6i!um?k z+%XVIEKqook8HL1yF$Sf#6*BtD>%#!CI={2Xz|6qXamId(rbm{|A^Rjm`eI>%5vxw zUvE#b&s5{Ke!b>WntJyxkxVR00n%&0KJcuFu-w+1huPT_+`I;PUf@;ma`|#bb=}aL zOVTYnistPIb4jRL=jImxuPt0Qu|{FfTmdKrs}_hCI^MJ+0fJ{nga$)zw+?1eRCg4V zKnc!xH5y2WGQc_Y2H(^Ymz4~__vIp6ldH{UwM_e~RFBe%-dxmxKon#-;QAK2uX}w_ z=<|XS+hFlV(cEG~`9{zxVRmiEXeEkII4H$3R@j9l4H{lv$hqKsZU|KU_H1H8aNHVa zKgSOEb712I(7!Us$0X@LDF0OF}TN(ct21BBYEWP669gL%%X6 zaL*bh_{2@r1^VnfL&V0bTmuOygb!9^D-Y|f3y=JwOmXliPK`li8iNTO5n~PN$Rl;c z6=5mj!BXk0-h z>J~s75Q2f9xjXv!39?$0ra@u|`0KfEo2l>(qUXTyt?@eryc+c5hU_^vr+q1S>YqQm z1hy!%BzNX~k+L>~Q6Ut1!?mTH&}OFqQWZ=qWS#h_X*xMIwG5?b_584BhJ)u{-MGRa zn*6tL!QrxTPKjU86yYhrEwn`&z+4H^c(k*vvy7YuS*;HlX_l^NJS#+;unY$Vhg|)?`0&sy(2Z z5y91RwL5p<%jqfE=a(t$d3Gk^F`;0e@uYw7eYFJiz}cW8e=m@)^12O+{8xYU4!ve`?feK=JB7VEI9!J^&Hb zgG3q)2~4(+E^Gx_-=cD}-f-*lp#D;Ox%21yVIs!sAW;GP7(irX{h|uS?l0h9~AZ`EFk$lai_>->QfFZTH7NKNmevoV|W-0nJjIk(wi>ZKYwO zO|gAxx`42**Z^;3Mf5{wj&7=f%|Fmq?2Mk=`Qe8Nqv;ofsiod)wX6H#0cKp{IIfs4ozkZBM4va(mi2Hj3eI}38+RT?1n|l?~pS1fZ@?p)<$Qx zR^6-n2Ub+#0K4)F8KGZo!@@|K4kZw~uLx|)TwA%E;lizY;h76aTQ=n$7FzUH)s+CH z{v|h^p}cOgtdXwj!e8=*6O^n+bYl!=GBFh{!ZL2)r3M96J!FAsYMP=Y4C%VAq5o9; z2h?VM@ZiDQly}kRR!V9beQ#@;!K1 z+IMfE5(QreMkOfoxy@FocB;mksQZitIc@2|R*!a{;il4OoeB2lH>;!gI9YXZdKFs0+D!M=U_8sJ&7CsFLo(ma9(Uz=wU zV9OK^x;Bb}jpdNa(tD%cVII>-sC{udy&44yqToAl?8c26Xr{pEyDk6S674k_VP|>{ zbor+xF;x$u(ttkG*T{p!3nct0g#`s24d1w;|97MtOh2KZugEHX8!|N)m*fj&j?;`7 z6WAotL{l^(6~UR{qgd?}2Ol7Qb1!}o1%oFy_n2oox66w%j2H~$SUxgU9NMjf%lJ9U zov@wA+JJ_nN^WH`UMq9Nr>r5vqMiv9qTpGG{f?}2_L?yeg1-247*?@xMjG5ERpa9} z>&8gdI-8gJDVJpt3RG(R2wIh=W^+RR#CKsC=LM{CQZc1e^j9=Fn){xoa2hRb36WrLE5#AEccE;eg9Ga*ZiROVq z`i$B_n&pP+IlCG#41q$#*mrw$bS$8|ii78ankoK^e4U!>)UA1IX0*2Z}al zEmVvcK|N@=t~tBLPqrUDhcx9M%E2KI{62d}BL ztE7{0{1(9ur${gT_Q~cAjj=Fjv_|&F3E56=dJ@xA^>@ATY*`Cq=EZn?Zr1p0(0*T) z?!qhqWF?zF(TE%jDLdzT^3|aTj)vh05+19!52a`u%g1Y>YW1cIoI}$2gA^dxgeaGB z!e~G7F}bVx#zzom5-fz}`W$9aS`BV&ic{_BiNC;jEog=?!?eu?@N*$?MYAEK8A!NO zj{fpXyBxF<8H%*Ewee#xER$>Pzw)gxTqD%%=$G+Z^iC#sMHMjA(9j_OqqpF;7jW9a zr*@UR8LiOgFFu84n_#%YfFLQQU83J?!vdKo5YjSfFr!G4>mr6L%KE61LH-F-PreaM zkP{0AcPX|J+-^;l?Qr_uoidc4{l+W8jyE(QAeR&O-kplNL9#`?N7{YkAvF$^CBe`z zMh%`i{#{1JQ=O3SDKWkT(UcctMaWz%5sVHxQ8x%=D8b6xG;zP!&F{L0jFfqB+PNQP z&HTJkP3}o%#b=Vjk2B@QW9(r>A=tx(f-fgUu;E#)iW)i2AsA3YVS=taUHN}%LJ3*B z{$r(`MS6qZYVf884EaJNDALZ@Z|oT=K+<*y|E54wh1B4vmBIOOSYCLe4V$sE1<0>2 zlpX)8a7shO&GX+hE&uf5MzeV(k5JZs{GbnZpYG>?z5kmzkmchMDQG?3S`C&CIBA@#e6;RiyyScj`!MobcGl&#gg@GZdz%(AR z?8Pp94>_1TG8%1FL+NMHE-e5dG9XK1BNc{(w51I|skUM>$|R8Zb2R7;<-pmQ9_FC+ zJin2s91RHUbW(JVZYhwL=1+BgUw-4etlpzhP13+d1u|!Q$#FJ~D~xk#Q>a$Gn{@Ki zbDp5W30m80L4+Nv3>e)g4NGs416ZJHBlcX2gxgk^U|14dqi28=QS`BQNL&1J$D*ZdLbZMoaWsB zKW1c6XG+<@M&nB@pm+X4{}>EQFs${D6&6ad91s@nF=IpItZEYAClg@j)|1wh5I_MW!4xQ{WerGh-uTST`Y1dk8eGUXY(I6gC*MUL5 zRiRz!oFwfL`~R!<+B?wwqlvpn#=SO}$x?8;qrKz0=uD?BCQ?AGbr(6jGAKmXfkUi) zYZICu0|rjeNQS0+sXQ910y;jgvDCdpI{f{oz(c2@Yz%S7K2HW5+6}=xN134**aux< z8iQ&#MRziS&A=0%5rCPXA9l9tw%$cISmQ>}=IOqT${k2~Rumlfu53-aw=7ZoclwlH zKIu~;GMds-t{;kjRHrj7cVLAZc6?$3Dlz!2z)%D9%S19+3G$$g9RuB?vfl9rWj15p zanXDzYh~$uVK#IzqOmcQIWf+&GuK>GXl{ZL`DMfGWaUz%;+GLlK?vVR<4>hp66-6L zdMK@Qf#zn=&k2cOFo$mG@r7mlV8zxlvTK*l;o^fYcf0pYwuypse$HgF1tgkTr}&ER z)(K8!9r#reLwWcaahu=2s}=XcVwuDIF{sIPZMYHlFZ}Go!wtZxC%vtKej)GTzyE@m zB0(A2B@DR6*mJa)Zq-5O3F3B@uDW=^(nQq z9(_IX(iPpxibr%T>bFV?+-+!_krm3 z>(`&cP;iE2bf|Za-~X;mCgeNPURS$j^3z?hACj35k%y&RKl5WSlXu0{Brocgs-p=t zC)??~nVvrNx+iIH(VIR>zgq9*k4)7h$NXe-FMG@8`aH@=Bk;VLt2c7&k+AM*a37i| zX=XDS2Q+Oy))iOcW~=BQ@E34Qgm+JnUy60`7Io+F8QNVfs50UOuKC3D?o4zRtSUi?Pa+7Nao(=;p_ZrSIw(W3QkK?fcW01O z!`;QqMiL{3A%nFiFcH9Qp_;7PG9*i`u*VjAp&Gqu9iCGFno2Y)S|G5;pq8~chdkpDqpN0U7yf(j8H9t zt<>ys`VT~>MbM&qy3LY*Inpq$VJ!raE^p%`b*< zn;qEUHYG7X#&{Q&{YOeUDt9;WXYnu%=1i%*2%kSFEKl*9lSAR`O{V9@wf|^2|Dfx9 z#mzOCvKcKnvfO5n8XJ{Nh~qZ8-OufG$CrA`JblxpU0JF|%(7T?XUj@mpA^FPn^V-R zL_{U2aMwuyLiamNSf1ehO^JI76uu$h&Cvp4dTvw6>!Tq`^?8u92ikwS{q@`qSTNu9 zCAYSkDa7ZXqp#&@_VwRf!Pn;2I`~2IReL6u*oRnj{pmG}jtos68rSWX?n33nCl|JM zoHnOS60ApRthLtWTBe`gPgr{9S$l8aVeV=3=dbp2jds3j0V_effo_vp$?T|t;XuXM z1OltfY z03e5{V;5Xv!Wn{fL~dQD8W?+WwE$erhu~*M-zrW2eVp@Vb<40=6A)L;sn;i!Gk{2TVr91b4UlvG{y+A=HNciPFdT}JKWB7AMn8K3{NKd%NFhYxzp+w4mmIm=6riG z#s%tF(~ND5KZF>{A4#{BHw7W16LU@e^8(MLgGfEOIrs8v!GSYL=zP%v2E>Eov_ zw15A{0ZHJp8vqZA;vlD&p;i+3ttai650t82bOu}E*7QgydPxjw{Mp;bNzX~8GyryL z99mRoW-v;c=sjtRiA~tjDUc0Y$LnLgA^8=sEHS#{RSSEfQ81J3*xlWQ*Gr@ced(!} zv$YC3(=3DiFukS&Bgtg(0lVrtyK?r&V0YmA^jO$alnH$w? z3qI}KcaTc^n3~;wRv0xlOPB>aKyXkY(@r%Fp*~y>o7^#QFKEU)esBj=K}?jey~KOa z1Rep77rXZkHw8R8QsjlxX=kn6S?wbUfW1j=b?Iuq`bb)0fXoD$!Z=UGa_iv2_7Z0m zj<7TDwBsjmv&NSK?G~nwoPpVzX#DQo&9d3Tz0E&&P0uy?jW~nm6v26CMG!w@>ygg! zBawIs!(Ue%B)rKD8%ts=HamdIwi)eguE<(uT2}Z9R~LpAHJ{kRYG(+qERqqQwx zc)Dk3570P?Z-0D4T;17o{r-{G6;eh~TE~8Clk+?-%bXn`&SYBqw0(3M&FEEV71(L& zyoP~2to4~>T-UTrZ$90Ij5^#jjeXJUo33sZf;G$8@BhY*SY}A{@5(1 zQg|1_LG_89t=i_5{(J*(HmmOEH^3ii%cO{yNZg;ke$;h3J+)OTcqO(`yR>$$Oe%yy zq-H$YiYD4TPv+En2HRN0_+7Q~^QKqNZ_U_pnKZ@dmwp%Aa9IGtRX2$c_+3`ZPgDCr zs#R~4AYVz>jazE+NCB48^>xcA31-DwJ`!Y&z zE=N6NEhs2X5_Uc}$ky1$VIZdJofD#L^&#ONbIPvWhkXmJas>Y^N#Dl>AD*gNblysW zzG5e_QTXR*pQQ`daS9PAu8nR2l{TpXW(9=zcb1n>*n3;BTE(-jieazWkLU2(C}Lux z_ypug&Ap=vr)n|Sw4!EF*HjgLi%RENr$2WaFGub_GM(B0d(^3|*)l8nXi;{MTc{5& z{74iS{aNTL9v%fnU#WSe%F@{`0jtV{?d+mKmXd5!)(!;H6j{cm>6SUTt$*;ONbI6>=)U2( ztQ-pODeMmD}kKtSXkXchq}H56p4wN`6&-O9jDv5bVYeeN2eadQ3`NW zZq1c-yRQwjT@DMgc+n!+0%4B#nDI=v$>I7C!*I0LsVTt4yYpf1`6QK8JFuRc^j+j~ zwy+aUGC1bmgk3U-m+~zZgISGNMh)ISHEXljby(q>!UfFP$a~cuA`+kbB9GRbMqvda z2+z(|{SP~B55n9a7My$+#qUR^@5T%s8CS1h>gyP*A1pLiSCj3~CuS>&ZqU&% zBAAl??Olz4j{s0kVJZxjLeva7k8zVPW`~3G+C-e|ybqYfNI=ZjrvbQRcL2*8hQ z&Eo>_yO>Kcog>SFYvp2+01p~;KR;vr=75$u!1!OEdyWLCM z>ku$vb37)Wd5%0)%Qo0vKWJU`!Sf$d`iyJgB9!p#Ei1>MHSI6>QFvA!UlCmOm&2T7|?q;3)dd^hwpd}UC{&-2a(Qq+MABTyt@1z}G zA0lwT$k5{a>}ub9NNpx!_us@up~XHQk@!Vx0bZF`(j3)$6qlxX@ZVO-J^twpCkN z@UZ;_;|mVm&PqUd~%!IzdS;QaQL823)iefWU$ zi;tZ))0JDYG~4oKPC^lKWG`DjfPl48Cp3^)br`bvDoqbTo=RYDIYBH!_vUT)_(L*1 zUl0UH0<->~v4lq2rt{~tX7c3vUFY3%y9T$aVE5L#6&)b9D+rE(xZI)2t?+*?!!Hrf zQbDTZ=fg2~0@@3#4rLTPCYJ|F?d$&;wYa}uyOt7EzeA8x+%DQ$jkYpqQxNzM5CiZp z*i~N+UB~Z7DN2}3JnWs(f4>8!ZK>5(9!t?_K!VKe$^f4u; zQ-yUp#qv0Aqc?&4t@4r z>ywEABatSOQcygNbQ_dOM)PNn1U7kAqqHTX5T@f&1YFp?W!{&j+!(imIlr^a(^70b zBAD&EcFX?##g>itZwx@ZM`6$3ef>VU4gSx`?%YeImNWSVaO<_KrBf9lhrtV$%5^#I ztaKfo%>1#j3iH(#B6x-awzJ+ z>DX00L7-*ah34io+x}eLHo8byrZvZ;s7}PYuWD+=g&v_4rn4+xcqI7e-TQ}nWzCBQ z3axvRE7}YrIBMiY?*sCmg21jhWbrlaQ>_ zfC-pW#T7sTx?Q3zFpEq7A`-V`%^ZSxWp{0!Fon?hZBHqYrHDBJntZ`v0K&oW;Fe?+ zU)L}4gr?OpeNqrFJwCQJK-y=Xub?&GGZE)gPpPWtQ7*PI8Zt~PFvtWc<6RpH6-Ke~ zc$-C;sUfhEX?m>f3HXa{DHSy!aq7YkwgDzk>+3wJZGH>^uLuFZ%Z!khHJm`8nUDr0;FCP`9**J!3ta)8)@XTyE2sJWQkTXm1~Fk=^l9p}gC+J*h>)T-9NxZ$$zeepX!q+9Txv7k|oUW5hJ zu|vPQURqcwxGmzpL4q1Z9Vg$5LYw=9(s{1DE5VSG8NQkS0G}&Fr97@gruQpw?EJ{| zoX&7exoeiM4Z2d`i-s)ACWi=%-C%LhYQc$b6Udy$C~({@gl(;OV_bW9u8g3Xrt6sW zBhi&OgK0xCF93r4BbG)c!9+Q#t4KW(q9p1E{}sHKxHw!v!81InQd$jHJKQq*og>^PXqN-4Jy zMCsCXyJ5gVF2FS8R5bJ_+{n*KU7!G3@U9G4UyIMNG(0JFDY!kASNtHP+DAQ9eaLAf zxGzJ`eZ_)Zlj}!A?s~b(+w>iElzcWL<+I$Y`7b7gDOUJ*a|ey1Eu%OH%c+MAP_bG= zVN&yAs?ETY+Tk%ykMA^QDSD{t{h3P%2*l!zb9Imp8Utm$9h5kM=K$V@i(PM;(0G8h zJl=otYOtYbCt%s9;b|DS;aM}am>3}H&w5}vAY>`!kNULZ=`83uVpM6Qz`7*Rd z3c2h#dY-=a{)0bcDh#TK2fRHO5O!TVA0WoHyVH6&w}C^Xc6V!*jFdr9r?z4r(P_#r zO@;J`x!o>8wVvxN#k;6%^4Vmjx>EPm9+BPoIM@8mxvp)ItI+~O%!-iBk_+CsGE=JE zus++wo&e_cQ>CI2x>~nNQ-bGY*{6g0!vNQ?WNLWgqCEJP6%rG68~1|Sto3BT!h!?5~?JlOL&rlSfeb$6r2^dZU|kxpWJi+E!ux zoiB(s2{G!INC_ZOim?<>nlVZ%E zMwF5<-tHy>-=1BLRNQCJy|oP~*Fvh8E;&HgX3vshM#VTChANCM{tl&OXc6kmF{OHO zyUvt2YR=w{9opF(bmh4T{t3zjx5K(243GG5Rx&O6x2sCU!xp$mqT;bNTZA&98ro(N zfgGy$VtdJm3dPE#wHB{gFRz~4Lh=)^C%71^qA1F&C^R!BKRSYAPgD&4nHRJD z0J55$5l)X?m0yY%Gw#{fEzCcEb9AqWPE%IOsWu^p`b|@_234>^3Zcw$=su#>R!smc z?JUegu2}75HExOtYZ=#bor~l!X~u{dymf>Nr<8-+ebjA*b58`fPt@Z;Efi%erlPw* z!Ur{?hPMxMGLh%Sv9Ojrg36&XOw`9U z9PTKY7~D#LeFOF5p8ST%mjkT-Pdjjhpqje%Y<(DE|1`X(m@{BrAV6ux7!kV#i_T`OfMBUY{U5 z(A6^$qaDbEScpX8s~NxIpKU`9RyTmHBOcyRb6mrJMOxt-V7?tQxTBSOv-+O>h9gdN z{r#JVbC`;aaP3y3X0bT3KFh5Uw>-$;q&@AG`t7@P&33wfAi8d$S!k{a#vgn+WpneU z!P4B`a^UwiT)8EA8QkxN?-PqM*=y^&Z5Y8rYx@f=M%(;F%Og{6SwDzNPc772C!A~kQ76BFD$6&KCNe8D)zskP3!Z`Sd+rU~TN)*oNZjsRvNZ9upWYb(Si*z6A=`qWl=HDh1#Kn#NG z(FDQt+3ye6SFn^)$=+c%J0aaYmqvH4GRA4xE7v0NQSPmlVR9Y^^YhE^-{7kUupx}N zQ(bzlx-lM@W~cF~)K+E7;4)p5Y4P_MhS>ca1!<}-D?r{aH!XCl+r3cz!1vRE@t(`J$s3Z*AC23TWNj-I{M>eiB?8MSj6Wep7?AE;K!2xsul%4yzE+V8w-`LxpDE zUmEdd-IRD2#dlcJrDQ4IG1-eAdO_FwF@4X`28X)3Q=3h(#9m-aC|NX@nq5$)-;6rp z0D85R>4(schm`4KE61arh!GO`Dz{edExD#RRx$+8^)Qrd+5h>}Yy>t&jy%0Q%iiUw zy|!^eHOEwL(-W?9lKlj6m(<&fi9oFh?Ly!O(}mAqL}N}_;bX|H&K%i$>qv)h2Co_yJ ztKsZm2lVdLSM=^J4NfCL9y+@>TV6{%tcOfGm;<*l9(@+?4tuKdv)7!R|MnYakp^M! zWpnSV`pxF|Wc|Da4qbmm+RV)lp0wV&@X&5ce?<&>K9E7Egmxh2YQ^YlV9)IFHwrbn za$ONr6qDcVeTi6vce*2+^6*Kw6A(~*GO-lowC>9-rwR(DQle}2O{~GJsJ?0}W+ihS zGRl#<)Hv^p_j7!(xZTpX!U%k@gj;G*=HLhNz8X-N4?iT+_x(tlu^pF z+MUw^Eh)jIr5g*c4$y{XWYcYo=GM~sSy1wM_v8-+K(5Y!IxwmB^EBBS7osH)0;X<`NYLqMt`ciOBjmel^Re}~%m4wHJErRQ7m!l1M!6I&S`ZdGQH=rq$Jm0&d_x&ZUz zxWEYWp0HJ=5dG2fY4+uiqEKu>RRE~<^E0_ns8u^p#F0kmw-6Y`BB1Ocuw>znetL4n z-aVqUBu|ZTySnL!)vG{^2Vi^q0d!Z3pd{$lbLM8V7j~aL3cmI*R!&o=A0O;n70$Xz zEKPddUwH8`YG+DT(4ArAdP)e}C&TTfoERrBl_W!Ag_43q#Ujgr1RxDrcMUiqJ_ZEq z6J0|e1D1(3%VCOt+Xo9tr^{6YiPjs{ndcI-D6W^xA_e0sA}6y z+YV(bNj{RH>MvCAvY@v6^ABYRdQV^+q2z11vymrF!Qjr+Mh?({L-mxrw*nR4y#SAI z6bhd4$CC?j>jFr~pIEM-M|m!uT=jDN5jdpFcYiroyJ27i_#3_#R=Y36QHuyi&A(_XodfmASj;h_y&pa; z$6inAoDArMM2?cAzD$vJ@$=Eblk8gV+N$cldii&f3r|K|W3;M@euxe%RTdo>`*yCL zGE_6PYlDvZ0#Y8fN8%cVDF3)>B2!5 z{M8QNy$SqvP5D46Zr9_MIxdj|hKdp!+Ex{+Hrj1!=56K9Ep23D5m+d9%6I0AN3e;o z9;!PdcRTy`8G+xX{ly>Ul~w3Fvb7n(ik}*Vx|&HodLSBewt;6vfhV8Cm8Ce?rJO@DdFE=hOg|P3Ay^ z#G?SQ2Lc1At1%6ticy-+zQKXXh^$k*<1f;N!$PHDz>-LFK~XOCtjj`m#7(e1+Bb%F z6?t-kj*eT4K6mdXFy;`B<_C&~T2=KUkG)T@p3K6#%V4_!%N=jIV z1f&E;IwByw6U$hTCcT4FrGrXu7K#A{=^d1SA%r3|gpz#wL8sn%%l*Fpde?o|`k%FA zLK#SM&Uv1_e{E|dRfGE8-rg+a1u z1HItYwNiKLT|&FhWDy~;5Y{1aXb{>%uIY%H*1s!FrrjLxF42%)`*26_>g(Fm5}y&} z5a#2#(IF%zXcFFX1fxCM52i}-40+ir#9D=^wuh?n)Z7`o%XI?cKpM$$h(>cb9OpV_gfR^p@P4WJU3Err#k zsbqyfHItr#Ppz3+1ei>H=7}VtBNxQi1IGJj=9ZW7!O+% zbAHuQ(&@rDb-_V}`XH!RU`Jk!0y(U1p!-6_gGy8Efxk1WaLxY`RK<=o1iJkUD^&yvz5JCIt`$RmH zs+bhm`{8)JwxQvIBoif7Tp>^tEUQy9bHFjsLy~$!xWOh)T7M{7zRPtUUR~RHu)G&(&en*bjfM5a5Ka4?2Tsv@AJGF zUraA5Q1OYZaYG?1uU4P?zHWv0zgJn|Qm<_{#uW6)g)_dZ4XDPZCwf~U{nK?Q`>n5I z^nq~O=qpeS?z_tVsJJuBC2m7TWmhqktdZ2Tqf=rU8WM!$2s&9zVqcyCLWKp@@5v2B z%kxk`jnuQ+qm9a{~$MsU1)6}4(5XzR%6E3wmseDU>l`i`Qsf1 z=olOoiKfAFvD5;vovp$T!S13CKlBH(G}{(G;MC0T;O-7Ry+G*snYC6lj)o01@BCN9 z%-()Lg8Lqz+LFNp4%1`8JBy3zm<&MJ!_EX60Dpfk%pTOuy()+L{lOc0DFFNC9*jeh zgEy5z*h2DL5I>2bAIF-bW@O74(mww^<>tQF*}bC?RH7TTyt8xcSI&(|{hiWe&9JY- zf~I1fG0oNG`W5S{DnsN!IlS#pH;cJh6`Q67W_Z2)8RwbL0LMMVt`F04?{a_^#Mr1Q zvLY?zcyp|XRJwYcj+M_IRvvo0{`A^nddV*@okwA|BDXnbB`0d{5DXJL&{pn}eS2=} zt^=t!BDAM|f~IuFFXaRs&C0E12~_me75yyag-0YiH}c!$xi^&oJ7+MA;ElvB!2Kk>N*;@kjy)d73Ws^?&FLh={MeTp?m>^JN z_$cW7^A$t|Akm8W)Qf2c*qG};0An~JxY3V1N;qEU`7~$7S7y32xnEf!h3GOXFX%8* z>kfjk?(zMg_Qhlw?JINlp-VU#vD?Gu|V~>fF^X>;_0NqSrFLP_I=C)b8urDq)4@! z&nLt(msNYr?;EqPTGYYWsu>ij&3~5K*WRUmw=Wi&ST>e6q2Z3naH;4czQKN&_?LJ)yUuREPVY|DS>Uv5=y_Y zNGqKfPj>vU@&+yFMC+GLdH2srdGn5q}-ARNZC^Csq?I-ZM7XFNxQSq!p8hd2OLJKU*BDhgv`2~oBd>pURfwOAO8+;|`)RlwmKSC2b z*=42G$|XRN2a;sWj>fQGlIELbcx3XfzOgr;Ye4}su$4T$#6PeuY1{X(Hm1mdOlp)H zVg@?kkk>Tky4UkQpZ(DUxGhKRM9W3Ic zJO3q7Fqd)lcrKD@1Sh4W;y2cf!>c(_9F5`kD~vZjh2P0*+||F^yz$LozI>)Z{;QTO zxI^H`hLm#Uc&8;jhw-cT6{^Zz;3egoK!fkFD6$z3e7k;1vFM<4d+EouM50>CKS{;@ z-~Dk2H;xjJs|4@T|@Gs=Qlk6 z$}niT%L@DRD(WGZ3g3hGWrtczy$P)bD@$c3^4LzF3Ie-CX5U12zCF^q1ss$(-Yh=P zfIyhEFOf4qGMvQ(;i9IN-RdOl#K}Y5|(q z(P&U&x36RuJ5vT({A9h17=OJ+^q1#}8USJ2|JGj@eY(fW6j0rktviFHQ-HUa0*6!x z)PVf_=l3etZTwFbKLD2h1gsiN%;a)Tj>55r)Xi-_M5hEv9|ediK~q5Kt5mF^@RIq9vSk46$$I+VB%YQyl@4mefx<2s9D~ zpc!{s4Z(IRZf#f)@Ur~|Ea@X&4zBBH5gS+41kv0ND`sZVwIJRO@98?T?a+RR@IzJp2w;&az8I$wa4?1+D!@3+A@2OZ5RHK2$t@HY5=MAKHJd*dz{QluYei9cOJtn)+#gxH3Y3 zgg~)+JGT^5cqhnI;Q~nNo_W0r3Lamy*jsN@bqCWBkCxG-A-kS>xqtI_k1Bq{wX^7&WAip=JIGJFhfU;0yZAmXpBD?ojk29h z-$UD2vEj_T^MVyOs6&kCq8O>H$fo zp46H`pX2>){@7uaD&(l1$j(oOAbV7jpCw7TOhof1v0&z$&%)i#jGDGdAk3|k8ykO> zoq$M2x<1IK__4H-1>~r?wTE1VDIEV{QFM1Tp0jJfVfD*XLywfwFB;e&AZkv`mO?3S z{@WAb(qb6&ZAc&v>(Y-W2}XboB18Upx*EQY+4v#c0DHrcv=e|$Cx=;iEY6Dbt7hc5 zZr(v%jL2cg@VruxN9L+B0eNolHg->Oq~i?m1WrjUDr#XmBIM`xC+AkJV5x|fu+c%H zU>28q4D5;AgGemW3LN&9F{Rfnz*mJG>MrQ?!<9*F`p4Vg|{`4Rc(^S;Rf{!jyb zV}#R!IR(uD#1*{pp$N6A%vtlWj-L;1Z+U>ara}y;w7YCULR5!*Vf)3u^eqF!Z?GZG zh~$0~?@`Z!q!}6JNS86--E>mW;$6?#e*1D_I#Ea|lIW=#b+lhqp#^33zMS}tDf=71 zw)Z~-Y(dUMK2QXFv3%x5vtt|U7JSID{C5T%|NrNP&eOji5d1%RUb;xxmrQ*SOG16e ze+Tp(Enb}H1f9Et1l5I%nO(se1(GdW0y4FRF3@~#^cUNBgBBT%aAT5fvMRC-);{n` zv22l3fRX{(I2s`TXasB=^}-r*EWlm5WcFuiKeq@tNO5Cn5ZW!5@0>y1FWU-12TJ zs`}YU!QWIKXFMDmuFc_TjUe*aK<~g%4U}GSza8<%8Blm1$|Xfh%Ka_`F{_O-J0HtA zn+~3C;R$C_*U5w(i+O(+oS~2)OuL~o0F?&|{BDp(1bWR>2&_vHLBR$`uRY+O)*u7v zac);L{oNT+0p($dt(J+wHa7R40dhf`e)ufjdjzUkKh$)~)$+K-Mb?A0$M8clgy85k za)2Rl;9(|cLw-c$Ew~nIqYF*xiYT>jLx|68`-@q|Z0Gv+Q)-_cU5Pi&7?mZ&$*$)* zmyJcDI39#Fz5=AN{lAcgq}lO-ry+1b?%Xzt3Bc;|>N?)fEzyu26lDbDw!gpy zu@t%jNin~IaW{s}D;V+LYOi}iXOMEbxYv{9Ou=O&gZ|?0vwj-MkU_8Rf(dGI|E=+_@913_)@kap9w>Dg1b_77{g&&W-XT{j zXr5~Vp0^l=1U?&%;SBfRqP1yWrh$T@@LDQqM2>(h<8hAm-}v$}+5-=HUGKK~#xY%L zC<4t~K*J&IX|%XmfKWQ&-i!a&$f34h;{OY+U6>}XJ)3t^i+3^fh(Jgrzk?|JcJl;D zdCSJ`Of4QvbBu7wXz}Ow@4xDtPE34179?foKfLx?45FZxK{GKw0xkvKu@Jb4?CO#4 zfloW3%<1#qEUo9CEv#>=X|{{5_sp=9a!*h+ej(+tg;OsMS9t}yPZiO^-MwK;%|jp# zSmC}wIL4>OtiIXv(m0y_F3RWu#3JyYtbsr!uyAL#X0(_CTS{SZ2?88GmQ&dD^E>g8 z2Pp_aRcQ))cJAoi__@UD{Z`T|e(3uZ0jq z5=x8NdDkzbDaHFjhCyu{gfHaR%qoDd&vn)f8AuB5bv0#1{g-`caW3$Z^|0Rr`78}d z8F`FFjCZZSIQejUAaw#a!4(H?17@GZx$DL29fnEZi7B< zfFhZEey8WKzKeDtINPg4OL&44_l1zqEqrg-)l1*9x6Rz5hn9{|PtI^fYWIg_@5Y+z0&0gC>3wBa)zp zC5ZvDZKD>Kcj0=H&|*W6w>d@7D~wwWl9qZO+CpZGzNT~UM~E9VeUq^Fq#^1h;J zT!n6b*cCPM8A3VZ;r=SE^@Xl8mRI^7#dGAZ?f(0l`QM^mVz*=ev!EAD_OC%N?;qI% zr{Ub(2`MivJ=KG+wkbl0+K%s6R0O6lX6*Lmv+3^k^#Mhm18@>#YdieBrmF;iD%l6) zwH|E8H`L7wNGDC3=F5;(XLMvh+9iDNwg%9E!fbo0jX{_D_sFR& z5eHY>qGh~X6%q{Ws*kC4DFtOx?0p%#F>ba`s^0-5T{@c{hpm4Om|jf)QepoK2~`i- z{A4ntIN$MX7lHK{AD#_4m`=GRenPl|S&-WuxZyYlLDxc1JH+|dqJ)|3{Ic{O|9i>a z-^5@JuP8DoTZYI%*$sQ}28M7~!N1q}xf&f+-S?3|^MlVymE|M&E%Lw&9nvqf!A zw}IQ1bpN;biI*C}FdocVFQZvUJ`a3m>gDmmmUcMX_i=H*c~9q+wJoRPCGJjiQ(SQKa>xIDKpi+rWlpgG%Xmaq~jS5I^rK*e>bz{2V)T z+1(gMxA{SEaRV{}3VH%8le6nLH1K}{mQ4TY`|p093j4+#{UvBhI9+I>75~Dj>xFgY z@`wsjwA`LU)-~>bTJBI34n8Y;>v>4aqw89%PSr&+Ae0jbDFE0+O?$Ad5$8gOs)Y7j zmvpvb2P64Gh+2J!3aqk>xNZ0YqHD!PUv>hQn*P5E zYh>>0j?ks&jc(2a(vJ8{jifUR3Qnf$?Pc><1`tP+*y(A;ZT z2h4tA(8x1zb(PLk?*^i=yLOGj9#NhvP`xH3$<`*pFJ5E$!hV?FhZ83XHGlA}J9&Y~ zcJg}!6@m*;80TM>gnFP2hmVp)oW~1JvwVIh-24FPSWbFD3LyTofgMP8>Y4O1X6dC; zxBtYaqEM*klEn)fNYFPX?yVzajs)6lrB`O>VsV~wA*P5cg}zUVT2x|BTU;j(XK0-o z(|B`PAH)Fg6&KKObv*@>(iQEyXQ6-idK4V`HP8%7$v;I?{V}HMfAaCu7kMBTLC2$} zKP6OscP04O3@+r3I{f?avj3HjFIq$D7Q7H+g};bSA%^nZzo^&T&}f=PZB-1ybYtFr z|4qHR@g~auN)f?l|JEYle`kU6fArk0R;h<)f+As!_?pgSq;^)&sUC|j(&cGD5hnny z6xG|>0#Sf6TEI{hWzzMI+-43gC{UIksO!qS_~dN7t3G+Zl!Y@CJ2ir1@4HREe2g;% zof|Di5#l7xISfoEkX7Lh!vOnCrHqV^^bOhrtHJWlYa|#&EN)k|80pN812L&9tS~4w zMnqNzm6#@O$lWNB$g5T6IJRGKWN5s19*u@uM7A?QFn}Z5+3dS^je0PhVptC*(&>uiwolp3aI5BcUWQ3gkS;WHA{xM zL^hPCU}q^Yoj~m?!Z=P~%1;MLPmGIGe__OT*bSyky_y2>q51&?@}7s4UwC38e`T#< z7oatr`|1@|-+;a~K zKoMixdqB$#5Xbe|H9#DLz{!{U*!wR%CUTd6ia8F&yzGRDhmWNtKCAGTonBvEI3%My z`-f9<1*U%{t0GmZ)6?HosiE7G#7k}C_Vi1RzuereN=BN5AC~=)JslO2Tj%*&V*0=X z>m1ba&p4wTaT#0-QIWZVE`JcG;wGJ_zDaMT(j(MjBt;NN6ANBNkQNw^6hefp9%Ds5 z3MD_B!Dt>UY8%U+p_*`MbOkbX!eORk>S%FnZjVJ{cxK%Tk)n$R{{%O3O@mCY>+bb{ zOdC*_f4Sp6$3e+L?kSl1=dp5*x}icfrZil(GWKXW(|+k7>X1bWSCv=yp!1gvX3vRE zm8f|F_VVZoj4#S)f^_SM0i8ilmS3}1jY}@OOyI5oC>7sWA1zta4EeYhW-Ks1HP{^8 zl3J?IL3kzEB~;@sy4 zgW~oTZSK>(g7T5j<7YTJpeI9kKOtey z`*1#eEnaLFt7rfMs=CB__iHi#>T0WWtXeb0l=n%dNp#Kat>E#F%u8%(>twuhaqqAH zv&CZVv|Lh8)eW}7)s+TI;)LHB_>~rm@nU=HJhXh96O1KYjX_K3hy%d&VmhPeqh~tje*V`SjoZKkgC}GQhtUnnqpjkaz5FXq?;ka890%IdY&Y zSw7o7d*b2FrC&o!Sg3UK#e9Kx^ox!y7UxJ&-1fUyJzj_xEBG8Q7LLw7-LHWrd4~25 z;OSRDcxz|ZvG;}C@o~McERW?#5O$$|=4U32N`rcQ)<>T2?TVk@3jerEEqGEDiN`_Q%ErBZ|o;LTyOb`(S?^HX%F)=!Sv>Qgx1wjFVIZkQV`3p zrP^x$1S6Pz39`U zMy^1snd3L8+ZTndKtr`~0MGtDYuB^xi&FOdA3b$jKl7>Fa|czq+VA>{?L(l?7(C5b z{pYaVBxe90zo;~IMSH3mu_n+HuOP#z*^&gd=Kd&Kdm~E2J0Lp14PL^j04WrVU-{$j z_xE4yb>sD5uk-&C>?1ce8U}&11i*x;p{-s2vIZ4@JNYjfRNq@E$Z8mvc^@Ph)En5} zgLi4xH~!$WOZ1-0bO!x}weu zjbSTr+{IFcu6sXs2SrH=;MJ|ExFA75V8^>>=FYlImyxTj;Eq6B9Li;Esrlkv9$d9F zAdF(s0hFo!v!u!t3@P4Xl7eL)m*ov93kiNEPJ zA>BE{DVG0A!C@G8%dTter1lQ9`Sryp)sG+Knx*!&>j+W4+t&viYMU)2{Y6>4=Yc6L zODiwWbf?c}GNqlpyQ8(rt3u_j0cO$ttbIM6a1Z5Xd$#$mNtosli6cQ#*~A zEoDon?tayy-t^wLgZfoigBY*qKZG0nG3elrkI!y6nRx>vE2fwhSv!IOPB1Gn|0x}6 zzj{zPGWLsJ+l!*c(Oin^l@(Iy@`w?s+y)?B(d ziqyqO18)__bkfyNk=;WaNz{92H}7mzK87V@kp}gh*oxzQ#kK}kgD3;4Vx}6DK;_N} z3%ht#C+X8TTwCZ($OBxiG9;7D>mfvnB$YkoW zsL*Ta#|naI;cD#eigQcw57Iw+&rK%w*G}8Oi}MXZFV1Vwb61y(?qkDiT{+g$OXDeM zdx1JLZlt`%m>p2UV^@;Q)L}{yzo)UI5~xFW37Uv7*MtWm5(1T;r|l}wc`wX12m)46 z3hDBBBsO z^uf(r4Ozqny_?FX=`Zdual0Y|&wY0Vf&aJX{$|2&@Of~LjGNzJcL3~hM>Q>ExPQLi z$qF4x>~<+gFezOsuVJph2$lQ{s#aA0A8V&>ifNX{FO;Hr1aLPhfJnXl87i3- z#O7Hp{b*_A=;m^p01y2o2=|mlp~)_TY>&fhrwcqy+}`q=klWzRbKO&cp2U%g2ZJh# zaA{=1MgJ3Jey+y&gkxeSqA15(H8Mz{wmPow1Tk%Mbj>q*W^r}7DBNEkx$tXAG!Li} zV|T-N>W3gg;4dC5)(o*7n}PRKEPzfx9A=e#qC`vJYi8U0TN;oD5tMp{Pt}EzOfKca ztZVt=vhu}>>As_OHMZ`m9`lRQBJ)+w!@5Qihu42P(ac{ld9Y;2Q)P`%gxk_^`b%s! zn$j|>1$pH~*0hISd)*9e+JZ-2F7zoIWv33&)=AUuHY*+OgefBNgAGplm%3hvT5p$C z_Z=HsknqGWc8^5H**}Cuk$KhV3T1X$%D%3YP@kS}9C$$F;Xs3i2b&Jz@f~{AJBwgo zt6R+8$y1Vrqy{XnJT>zhI*!@bG6u^r)ksbEoaXS=#;s*XVO*_MT7bC5N1V3=@3CrAD8WY?`Z%X|lrQU@ zOWEQG2?do$R5iEo&?-y=kmT}dZkeGp^Z*~P;zJ#i3-yisERhFuMLgBHNnwO^-i<^b zNSGy-g;x%TIgy&B?1Ldnd~csC%G6_}Ih=dtL7f=YZR?iZZl+sQP7o?HJ**cMzltN+ zc$_vHFF;vblh4UR4g-aJ-!Em;mP*ik9b{cnC>U}q8Ehkr4GUB~N_5i7sAd6)rv{29 zkuR>Av;3H)Lq5b$G}PC-RC9VJO}l>p5pfKbiMttOZ(vtexbvMH^B5pH)OWRin5nM? zw4-6ZmKxFGg8WlHO478oUlx4AD;s7gHQ2P7{7yYgjgC*t=Op&*Y8oSGKaEGpm#Om? z2Uf8zq%f&aPvbVeL{G;$f~lh+j!bKz$lkopQY z!MbS^@;=yD$S!D$w2w?F^g{c?vj&F-HddG#fXTMye)XQ6dc&e}eMt&BQ2W|vAlayw zn*0$HBrDm+=6&O!!>A?-iDS-+`T^R_p#wnb*~9amC&uUFwq0&X#HtdirKjB*8pvP@ zf4=HA8lqS`oL?cDa32jNfwq6m3I;TYQ&JgIOz$r_fbX)_OW4A!LxKojq3w&xz`_tk z*4epKC6uvJH{-uc^5ggk(J++2p0#i|oNzTKDS;)g*Vj8t74 z+JaV71;x(e+Avq8Bp8D04=4J5j&U}^btYi9*cM%9fjjoZVs(oIVX|{86YlOHO9uG@ z44|!Ex%MtWN?=fS`%k2J`||mAL^xq6l?b`%g=0QB*e2;9^$#+^mMt(wMps ze+-9m)#DxNiNs=9YlBg*)|fIXQ3g6?CBk=85bSfktW$?*sW{i`M0)gurJp)Yu2B)V z0sc@Xlq9fFWQX)Y_QO8yEia!p%ksRxC!pfbeDe5dtOs?~vXk5$W$dl_#jV11o8rt+ zRB94viWYTH!f0;TL1Ux~hsiv+Zx@uSPx`r7F|=DZP{ zP4g|-@>B1>SHE3YG?tl>6jU)y)%9M!YQb&OZ5rf9%46LNXE)F^NTT>{PRXds3Jgza z6X-`%eMV6HB&@^C8Ht|CJ6T27EEiAWJgYuW)TCi~ZcPZMC^8$K*qGS_;mlAWEVdT5 zAKBs(Iyu9swSPW)&RQ#X;{|Xl ze8+#LNvw-gmxmjMAzmY|dL{PuGZ6A0p?Y>kSZ~D-LGUfg4R>clvkXirb7QTGJ$OJ8 z3A(s~^7r1c$JzQaW|JhsVidb_4Bv@a}Yh0Se15E$aAq&3NKg}F^hS14tA zTG`cyq(p3(G-O1MmmlgE;rLnO_8ZPC8qG;}80^@MA+zpPIj4W|)0EVm3Cnd=nUeGErP z2?7!V%B%(5V6g@BdsUAt4|9f6fh@A#j41J#8=mH5u2Z@ZC9u6M?A?@EFSu$-LAglR zl>lfbO86M?ZkIDj@*xMqU)tB7fi#-y-Wtt!8P%mFB1aR3$F$p8M(1V9US3#9@TPK} zS<7M`g2+vKLkG$}7D7KV5You`6&u<-BIGg!iVYg3`)I7RK?5OQjeY2aM|nc!p@RTItPC1&O z*8)LV$SUm9QNFxT>nighdF{Eh3db)6lG$5Herq?)Ix9qdn?1sFL!CxKjhHje)PZ_5 zM{{sg{U+xPuccms$(P&`rbat3;&ivUVz=XNcq{#=Jzz;JBg7~0uVQ>Xp1fNbJuAV| zCNTUYK`MiJ5(>ZOe{?aT5EhiVQpL-At>>*b3fzt|9ujyTtv>w^<)ND1!#I-`Ifm&P z+AY*Z)7geql67T;$w1(JdkgORqqUob*9sE%%lUds&(^*@{ZYer{EBwy zrs37LCL!NbG18RIQmA!P04^rh^<~Z7r>(hq5UcGUvYM1=XWv1=kr2c!Y-)=#fP`)@ zo_C}-CX-2~Lu(WwhVIc6Kxu(J>xvu2Zxq``!2ru0kE^8*$40v(2gp}YPu1iDR6xM; z$X_?zJF7lsspnCe*~n@ePR~`+4Q85Z=qHicQ>((oc@bV!f|-~5AKqVNPc2S#soc+3dFF1Eov~^?D z4MegL39eK6MJ8_oMU|V}u0K0^QKOnXH}j81D5o5VtJd0Nxi3FU?zPr*>l~&1wDA7f zYqgeCvMx(~E^B`qfv{l!+KS zoaN7&4ZC{JPEy++po&vhW74Sj+op+`Y+h0RyKk&_OYE&s3CC^9rWcF2AQTHzKdGm! zq}B@FjC@jjNPVfXFg?h}rk}e72dR?2|i>2wM*JW1E*57RmeOy_} zKmZ3?Dv#6LSjn}QvOsnz50G|iZePW_! z^(&TQtC;w_zTA2z!4T%lz#@5K>&{Z46zT2%fU)3@z#jzRwj(fdM#40&qZ9KMDQaHT zg#9GP(sv!w@NCAUm5pjfgQ7%=(g_}#1mjSL_{#23x>r)L)Op_0)5l>%3GqHU&`V1> zfEK9%5;=<$)-T-Kr}oa5w$7^pN*WOQgXrpD9Lm1dbe=rl_l8{u>t z%9*+e(VE5nP^@KNq^OAvy{LDRB&a;=3VU)0dQOr_363_PF-rSK6z$LzZ6UX74oPuJ z1#!!O@nSC-Ye1c`@LIUc%d~UnLeUXFJt#NwSsE&`M!&c7q3gk&G$FJ54XRAv@2OhY zz$W-zjah4_Q_eVwF>R&h zG-HViNvCe>B(BmsfkA?E{gT=}c|IJ#A|?~Z-$agWG<}o|VBFygR zH&@K;J=AF9G9hO5$l^2v0M^vnVsXAX$FcutjhIQ~Rh~;LFDEMtaT(zR!!% z6WV4jbl*O>U7c_7M|1EI2bC`#NImz=7E-9KMQ4EaL_>~zrB`}PxG3%{Q zzW0+aPR;Wp%{8NEty^T49)L_PVXOarc8ANE#!Y7YwWCet_BDJvcHP%A;&OV-J^vjI z&n}k!>XOjRsDQ0Y3n3r7PCETqf;g(xRuO@0p8JKDdfjUR1WbIDUCAQ4G?Ddqk`FPB z$o4%NQX+}{vYA14FF4T@>X)8dzUQBtw+(9XOH)?vmhL;=GWao^c!aG*48{nmJUi;j13t{=qa)ox*4P!*6w zvngy09B)Ouqs3p~{{Uu6QAjIIxjo|#PHS;6t(071u;0~telk&MV>zjt=3}g2)|jkz z{klUrM)b&p^{i*?MqMzst3YCp&lGBg^P5_GFv+U)UUC9nLM#?};;1qQ3XrL><7Bgz zh78-CysEsnldrXF-iBSpg$58BlH8AO%@Y!{G$GkOZ271n)a}nY2lFUBiF1%y!2e=; zu4$FoY$12@)~e#(9X)a@%Xl=yuKkFxe{2fBT(%UY-~#8H46YXKJwNSr5qqT(F_{7L zbF3d-?)VUpy;8RRR9E$Ih%^JGMWxy-vCXWf5VBsRtNMRd+q-B~HrKcb4XjLmqX3Bq zYH~yu-dsV`hWcX}@dpzah@g5-qxJRIZq1RLX;UGlo7`oEY)?&C$H$EF;gLxoH!aFiU)!godvag6%l< zjY*!Q*^s~y595XM<>UqRI9AAAxwaZ{1+z5QI46gHNJk}!UD1@SdEmrBnUsbAhjtI) zu&bxWO0LE+=%#{Ft)vUi4-<8g^G z%qTIOAGt-&l0sGS=je%-Pt8~zrG&Z@)1unmAr?xkD-xo(m7*Avuum@c(*}HNVd>Ak4zY#S1&J5FA2ypN0@BQpz+6$O{A{*mASbDcs`-pLJs1r^wh74Jp+Ph*%|975i`uN2#&Pda*P4t#$*J}aF+b2-Xl&xf4{+|?vI zx+hQ&dO$!k=fxQx;zNd6DS*-~$uLY~8ZA>Whv!hNMf;e_y-2vhYR(UW#hzhRmzyT8 zF}_P|jbm3<=+0IM-hX~E4tK++!F4LOS;pW1&M+op%x4qV`mtQ-r#OYbKw`N?IM+;s z*_GVUqgEZt=eEMG{%Ao$`QEI`XFfyixdW~+&~*Lwi9mWbsnn(jLh0%;sCg2crh#tz zPKn#IO$PuYI$I~OFM?Ny!<3MKHOSie*-X4uJNO6?LOkhCX@J!E%tCxvZgIk>2=9c1 z6u=J|%=9?v6bf^n99ddFDzrjN|AkcuRR-j?drF33K(k3w63!eJHK|yzLNOaxfl6BfPG|v1mvMniMLS$ zgOB3FaD%(Djl4HTYRSa?AWC8R$Y&tpA+!BvSaIn5;WC4?N~LD9nS0OZ`dUd11~dNs zVhgs6mu=}(%o{P9*C(+WirN#(=`g9QTZbK;JPYN3^H|6WnX?0%8d zn)Su3g$jFZ+{HxP+B@8=F`6AEJK&AGn2KBFu%3sAnzv88ffEy7_|Q!Bx(cXD_tPY1 zIM3xU;&io6z}#YpfN>NopCh;k5lF*S{c@=mHBtDi$+>7eBdb6wj$wH_A4xA|IEQt(qh6~b} zN-sY=Cu}KnclcB$-+d2FRILxD(Uzu9)@MxwY+i2bxgYx=lOf;$V{)1wr*>RG(c?>7 zw*DxR`Jm{Ed^=O?%bmOVm<7^u4QtQPT@!2!xGDK?XMmD``=$fdcUvQsFFbDJwc2s_ zezNGXTe2Og?@Ml8wF?)1BmQ!7Sm4M{;+D-8Nmbp{`~-U}iGi4vU7gTXwZ59J%CsujK|ZwgltB&3iEg=Lx6?xNRf*mDimSmnm&=#u8{`l7&CAr7Ippmf zsPb|vA5YFFL>dY{*49?LKAUJI!jzkD@jgD}fX)dGgA%F;!>Ph%>lY&r7k}d5tXWzi zDPrgrR!aiZwY4K8D&@H>4HpbZ{p6pr^N8*2$~MFLad+Mp+9_fNRjgnCGHYG?V7CXm zqKos+FRjg_L?t;p{X6p?^b_$7y6Ic!5|vvzyHbN?sp7V)Hwh4ILMw~b;M?kMQL1OJbH zgW@%=ZM{}Fx2rXD?YaV`hjm?AVkNSz13#Eb1eY5e)b(P}S!ftF`SS4eSx%^T`xwY^xXY-_9C9lldeA3vLJz>@2JS)Dr_T?Yf=H~@jpHycbcfflI zq!o=k+_#HT>Te3^WkxNw=kcXPOqWzriG%b`HrJmW4>I;PX8BPnqYc)r%BQ*v<~!l|dG@Q}vH}QFVlo zu@v6aW--S@F*1CCW$QudO!;wQ_PAX7rpCrOvlC}&03Eb5YRGm@Th_G;`7jipkxp%S zrIYnO_|x>BhN}am54Nwyc4p6s@YhdWnGwmuH$`?5il64HB?_G^No5n6sF%+4=V57< zB=K3lyt&EawGaeJyZ|a|t?wV}kQ{dQ5D9NNEastn-$1;cqF3YXaVSiA->OJoO0la# zzR^i))pT0a{7Uw0RUM;}Ad9Ub&GnF&$;ci?O7vbJ{f?A`-wjKc9FlleG09)ycCr`a zI&%U(L=7I>(_7_a=7zqY58oWpgAdgyAA2!RR5zVAo=cl@Ij=bG0 zJdW|+#;NRUUlgrJYO@BWuYY))J^ykc+nC0!t*e^>I3xS4kHe8Nr-4BaOmT>qHxEPY z?tw^Y+F31aH(e_$cM;uxD4eQTXq%Ic7NNy2b;bB+^@F1}z0kBFy=mKm#=d>$=I)9l z?s7JM@f@~xY2E)az78p1azP6I2O0&*89+Yu}pHj~y5ntzJ_hS!uIsoH*~|iosx3+N?9iT!S^o4&mD%wephB`rJa} zvz2rudz*dd?u{BNO5Lkyf3eDbp}*K(qa=W8R6h5RuYIVB*4XeiUNO6U-1W6*PnnZt z`R7=h_S&pQ!@@%v>{G+EnHQiz)xV+@*CpzeHPw`nl-StlNx;MGphUHqnwp|F{rknP zeSViY{lP1F(Z+o2mlUd(^eyIFGC{XO#DbK;_@Z=Y8z!M9qcj~t=ft6bmD7-X%=2ha zN&~KIb8;R>MU;Z8y%PGw?V*C}jP%9@UlBBEbfCA23qHZBxN2m?J577=s1px_|4hzH z@Ho7pL)%O$TO8%tbJQwoj<$xc2+W*KaBELhBD=24Cr_Ea(5SF%tD@ZA`dx#T^b^asdGP*`c9s^g59-I zf{;iaw!m%-zkz3P^ANEEU-j#g`R)VTUT|f7Jud!Z$JaD{_>}jDyI)6Ez~jBQ&%zw8 zug8uvPkx)leE0E1P+o5wH_u-DeQx&=-rvMPkAM7M@#`=DK-;Wr;PqN${K8B0dX(hV L&*z=}`S$+-aVnxM literal 0 HcmV?d00001 diff --git a/NeklyudovMS/docs/data/task1/results.csv b/NeklyudovMS/docs/data/task1/results.csv new file mode 100644 index 0000000..cea3968 --- /dev/null +++ b/NeklyudovMS/docs/data/task1/results.csv @@ -0,0 +1,31 @@ +Структура,Режим,Вставка,Поиск,Удаление +Связанный список,Cлучайный,0.07007737499999989,0.0006544170000000182,0.0003327920000000262 +Хэш-таблица,Cлучайный,0.043278625000000126,0.0005041249999999664,0.00023345800000007522 +Бинарное дерево,Cлучайный,0.008526416000000037,9.408300000002257e-05,7.983400000011187e-05 +Связанный список,Отсортированный,0.13493312499999988,0.0012999580000001565,0.0006884169999998857 +Хэш-таблица,Отсортированный,0.048969957999999814,0.0005084579999998784,0.00024320799999988374 +Бинарное дерево,Отсортированный,0.103865667,0.0009378749999999769,0.000703750000000003 +Связанный список,Cлучайный,0.06731966599999994,0.000668082999999875,0.0004018329999999626 +Хэш-таблица,Cлучайный,0.043154374999999856,0.0004823340000001952,0.00024004199999994036 +Бинарное дерево,Cлучайный,0.008746917000000076,9.750000000008363e-05,7.454100000003905e-05 +Связанный список,Отсортированный,0.13605504099999988,0.0013472089999999604,0.0007064999999997212 +Хэш-таблица,Отсортированный,0.044353584,0.0005022089999999757,0.0002355419999999775 +Бинарное дерево,Отсортированный,0.0875441669999999,0.0009309160000001704,0.0005734159999999378 +Связанный список,Cлучайный,0.06584004200000004,0.0006574590000001379,0.0003679170000001619 +Хэш-таблица,Cлучайный,0.04198924999999987,0.00046887499999970217,0.00022008299999987102 +Бинарное дерево,Cлучайный,0.008201666000000163,9.141600000006633e-05,6.500000000020378e-05 +Связанный список,Отсортированный,0.131494,0.0013212089999998788,0.0007440840000003668 +Хэш-таблица,Отсортированный,0.04231241699999977,0.00045720899999990294,0.0002253330000003828 +Бинарное дерево,Отсортированный,0.08590329100000016,0.0008908750000000687,0.0006914590000000054 +Связанный список,Cлучайный,0.06636370799999991,0.0006459999999997024,0.000381874999999976 +Хэш-таблица,Cлучайный,0.04220029199999997,0.0004550420000000166,0.0002180420000001959 +Бинарное дерево,Cлучайный,0.008514166999999961,9.845800000007898e-05,7.695799999973829e-05 +Связанный список,Отсортированный,0.13364512500000014,0.0013258340000001922,0.0007597920000002034 +Хэш-таблица,Отсортированный,0.04282124999999981,0.00046591600000001065,0.00022437500000016541 +Бинарное дерево,Отсортированный,0.0862158329999998,0.0009080829999996709,0.0006712090000000615 +Связанный список,Cлучайный,0.06781329099999978,0.0006859999999999644,0.0004325419999999802 +Хэш-таблица,Cлучайный,0.04273579199999977,0.0004545839999998691,0.00022783399999992682 +Бинарное дерево,Cлучайный,0.008394375000000398,9.254099999989052e-05,7.054100000036811e-05 +Связанный список,Отсортированный,0.13225183399999985,0.0013435840000002308,0.0007666250000002428 +Хэш-таблица,Отсортированный,0.04290666599999993,0.0005269579999995777,0.0002517500000003281 +Бинарное дерево,Отсортированный,0.08622245900000003,0.0009014160000000437,0.0005397080000002497 diff --git a/NeklyudovMS/docs/data/task2/results.csv b/NeklyudovMS/docs/data/task2/results.csv new file mode 100644 index 0000000..cd7f2c5 --- /dev/null +++ b/NeklyudovMS/docs/data/task2/results.csv @@ -0,0 +1,16 @@ +Алгоритм,Лабиринт,Время (мс),Посещённые клетки,Длинна пути +BFS,10x10,0.3340541999999891,53,23 +BFS,50x50,3.734349999999953,640,427 +BFS,5x5,0.07042079999999284,8,7 +BFS,25x25,1.392629199999984,232,173 +BFS,100x100,12.758183300000004,2495,1171 +DFS,10x10,0.07979999999996323,35,31 +DFS,50x50,2.704262400000035,995,435 +DFS,5x5,0.019816699999952725,8,7 +DFS,25x25,0.8116916999999724,316,173 +DFS,100x100,8.950549999999957,3219,1243 +AStar,10x10,0.07624989999999165,23,23 +AStar,50x50,1.6550292000000022,496,427 +AStar,5x5,0.023187600000018627,8,7 +AStar,25x25,0.6458209000000048,186,177 +AStar,100x100,4.468516600000005,1286,1171 diff --git a/NeklyudovMS/docs/data/task2/results2.csv b/NeklyudovMS/docs/data/task2/results2.csv new file mode 100644 index 0000000..5b3e6fc --- /dev/null +++ b/NeklyudovMS/docs/data/task2/results2.csv @@ -0,0 +1,7 @@ +Алгоритм,Лабиринт,Время (мс),Посещённые клетки,Длинна пути +BFS,maze_25x25_wo_exit,0.0,0,-1 +BFS,maze_25x25_empty,4.057983399999965,625,49 +DFS,maze_25x25_wo_exit,0.0,0,-1 +DFS,maze_25x25_empty,1.1526208999999898,625,337 +AStar,maze_25x25_wo_exit,0.0,0,-1 +AStar,maze_25x25_empty,0.19920820000001171,49,49 diff --git a/NeklyudovMS/task1/__init__.py b/NeklyudovMS/task1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/NeklyudovMS/task1/structures/BinaryTree.py b/NeklyudovMS/task1/structures/BinaryTree.py new file mode 100644 index 0000000..a134d7d --- /dev/null +++ b/NeklyudovMS/task1/structures/BinaryTree.py @@ -0,0 +1,90 @@ +from typing import Optional + +""" +Двоичное дерево поиска + +Узел — словарь: +{'name': 'Имя', 'phone': '123', 'left': None, 'right': None}. +""" + +def bst_insert(root: Optional[dict], name: str, phone: str) -> dict: + """Итеративно вставляет, возвращает новый корень (если корень меняется).""" + if root == None: + return {'name': name, 'phone': phone, 'left': None, 'right': None} + + # '674' < '722' == True, lol + current = root + while True: + if current['name'] == name: + current['phone'] = phone + return root + elif name < current['name']: + if current['left'] == None: + current['left'] = bst_insert(None, name, phone) + return root + else: + current = current['left'] + else: + if current['right'] == None: + current['right'] = bst_insert(None, name, phone) + return root + else: + current = current['right'] + # Увы, это самый лаконичный вариант, который я придумал. + + +def bst_find(root: Optional[dict], name: str) -> Optional[str]: + """Поиск в ширину.""" + node = find_node_to_delete(root, name) + if node != None: + return node['phone'] + +def find_node_to_delete(root: Optional[dict], name: str) -> Optional[dict]: + """Поиск в ширину.""" + while root != None: + if root['name'] == name: + return root + elif name < root['name']: + root = root['left'] + else: + root = root['right'] + return None + +def find_minimal_child(root: dict) -> Optional[dict]: + while root['left']: + root = root['left'] + return root + +def bst_delete(root: dict, name: str) -> None: + """Удаляет узел и возвращает новый корень.""" + if root is None: + return None + + if name < root['name']: + root['left'] = bst_delete(root['left'], name) + elif name > root['name']: + root['right'] = bst_delete(root['right'], name) + else: + # Случай 1: нет детей или один ребенок + if root['left'] is None: + return root['right'] + elif root['right'] is None: + return root['left'] + + # Случай 2: два ребенка + min_node = find_minimal_child(root['right']) + root['name'] = min_node['name'] + root['phone'] = min_node['phone'] + root['right'] = bst_delete(root['right'], min_node['name']) + + return root + + +def bst_list_all(root: dict) -> list: + """Центрированный обход. + Рекурсивно собирает записи в отсортированном порядке.""" + + if root is None: + return [] + node_values = {"name": root['name'], "phone": root['phone']} + return bst_list_all(root['left']) + [node_values] + bst_list_all(root['right']) \ No newline at end of file diff --git a/NeklyudovMS/task1/structures/HashTable.py b/NeklyudovMS/task1/structures/HashTable.py new file mode 100644 index 0000000..7200915 --- /dev/null +++ b/NeklyudovMS/task1/structures/HashTable.py @@ -0,0 +1,57 @@ +""" +Хеш-таблица +... +""" +from typing import Optional +from task1.structures.LinkedList import * + +def hash_fun(name: str, size: int) -> int: + """Принимает имя и возвращает индекс бакета для него.""" + if size <= 0: + raise ValueError("size должен быть больше 0") + + hashSum = 0 + n = size+1 + base = 1103 # ord('я') + for letter in name: + hashSum += ord(letter) * pow(base, n) + n -= 1 + return int(hashSum) % size + +def ht_insert(buckets: Optional[list], name: str, phone: str, blen:int = 50) -> list: + """Возвращает новый массив бакетов + Вычисляет индекс, вызывает ll_insert для соответствующего бакета. + Функция не меняет размер массива бакетов автоматически!""" + if buckets == [] or buckets == None: + buckets = [None] * blen + # raise ValueError("Длинна buckets должна быть больше 0") + + size = len(buckets) + index = hash_fun(name, size) + buckets[index] = ll_insert(buckets[index], name, phone) + return buckets + +def ht_delete(buckets: list, name: str) -> list: + """Возвращает новый массив бакетов без элемента с именем name""" + if buckets == []: + raise ValueError("Длинна buckets должна быть больше 0") + + size = len(buckets) + index = hash_fun(name, size) + buckets[index] = ll_delete(buckets[index], name) + return buckets + +def ht_find(buckets: Optional[list], name: str) -> Optional[str]: + if buckets == [] or buckets == None: + raise ValueError("Длинна buckets должна быть больше 0") + + size = len(buckets) + index = hash_fun(name, size) + return ll_find(buckets[index], name) + +def ht_list_all(buckets): + """Собирает все записи из всех бакетов и сортирует""" + allRecords = [] + for bucket in buckets: + allRecords.extend(ll_list_all(bucket)) + return sorted(allRecords, key=lambda x: x[0]) \ No newline at end of file diff --git a/NeklyudovMS/task1/structures/LinkedList.py b/NeklyudovMS/task1/structures/LinkedList.py new file mode 100644 index 0000000..e2e876d --- /dev/null +++ b/NeklyudovMS/task1/structures/LinkedList.py @@ -0,0 +1,65 @@ +from typing import Optional + +""" +Связный список (LinkedListPhoneBook) + +Узел представляется словарём: +{'name': 'Имя', 'phone': '123', 'next': None}. +""" + + +def ll_insert(head : Optional[dict], name: str, phone: str) -> dict: + """ + Проходит до конца (или сразу добавляет в конец) и возвращает новую + голову (если вставка в начало) или изменяет список по ссылке. + Удобнее возвращать новую голову, если вставка может быть в начало. + """ + + newNode = {'name': name, 'phone': phone, 'next': None} + if head == None: + return newNode + + currentNode = head + while currentNode['next'] != None: + if currentNode['name'] == name: + currentNode['phone'] = phone + return head + currentNode = currentNode['next'] + currentNode['next'] = newNode + return head + +def ll_find(head : Optional[dict], name: str) -> Optional[str]: + """Ищет узел, возвращает телефон или None.""" + currentNode = head + while currentNode != None: + if currentNode['name'] == name: + return currentNode['phone'] + currentNode = currentNode['next'] + return None + +def ll_delete(head : Optional[dict], name: str) -> Optional[dict]: + """Удаляет узел, возвращает новую голову.""" + if head == None: + return None + + if head['name'] == name: + return head['next'] + + currentNode = head + while currentNode['next'] != None: + if currentNode['next']['name'] == name: + currentNode['next'] = currentNode['next']['next'] + return head + currentNode = currentNode['next'] + return head + +def ll_list_all(head: Optional[dict]) -> list: + """Cобирает все записи в список и сортирует. + сортировка вынесена отдельно).""" + records = [] + currentNode = head + while currentNode != None: + records.append((currentNode['name'], currentNode['phone'])) + currentNode = currentNode['next'] + records.sort(key=lambda item: item[0]) + return records \ No newline at end of file diff --git a/NeklyudovMS/task1/structures/__init__.py b/NeklyudovMS/task1/structures/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/NeklyudovMS/task1/util/__init__.py b/NeklyudovMS/task1/util/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/NeklyudovMS/task1/util/randomNames.py b/NeklyudovMS/task1/util/randomNames.py new file mode 100644 index 0000000..2e08f82 --- /dev/null +++ b/NeklyudovMS/task1/util/randomNames.py @@ -0,0 +1,55 @@ +import random + +names_pool = ( + "Иван", "Мария", "Петр", "Анна", "Сергей", "Елена", "Алексей", "Ольга", + "Дмитрий", "Татьяна", "Михаил", "Наталья", "Андрей", "Ирина", "Николай", + "Светлана", "Владимир", "Екатерина", "Александр", "Юлия", "Павел", "Ксения", + "Виктор", "Анастасия", "Артем", "Виктория", "Максим", "Полина", "Даниил", + "София", "Евгений", "Алиса", "Станислав", "Дарья", "Георгий", "Вероника", + "Кирилл", "Маргарита", "Тимофей", "Арина", "Руфина", "Илларион", "Стелла", + "Роман", "Валерия", "Игорь", "Алина", "Олег", "Диана", "Юрий", "Милана", + "Василий", "Ева", "Никита", "Алиса", "Константин", "Кира", "Денис", "Ангелина", + "Вячеслав", "Мирослава", "Григорий", "Эмилия", "Леонид", "Василиса", "Руслан", + "Стефания", "Арсений", "Есения", "Антон", "Яна", "Матвей", "Любовь", "Семен", + "Надежда", "Федор", "Софья", "Лев", "Варвара", "Егор", "Амелия", "Борис", + "Агата", "Захар", "Камилла", "Давид", "Олеся", "Ярослав", "Людмила", "Данила", + "Регина", "Марк", "Каролина", "Артур", "Нелли", "Глеб", "Инна", "Платон", + "Нина", "Святослав", "Римма", "Родион", "Лидия", "Эдуард", "Жанна", "Вадим", + "Рената", "Савелий", "Алла", "Назар", "Снежана", "Демид", "Лариса", "Филипп", + "Злата", "Тимур", "Майя", "Клим", "Эльвира", "Дамир", "Таисия", "Илья", + "Роза", "Виталий", "Азалия", "Степан", "Лиана", "Богдан", "Инесса", "Эрик", + "Ариана", "Алан", "Юлиана", "Лука", "Антонина", "Мирон", "Клавдия", "Гордей", + "Руслана", "Макар", "Елизавета", "Северин", "Александра", "Моисей", "Агафья", + "Наум", "Серафима", "Влад", "Фаина", "Кузьма", "Пелагея", "Ермак", "Ульяна", + "Тарас", "Марианна", "Остап", "Бронислава", "Архип", "Владислава", "Фома", + "Станислава", "Еремей", "Зинаида", "Прохор", "Раиса", "Мстислав", "Галина", + "Ростислав", "Валентина", "Серафим", "Евдокия", "Лаврентий", "Кристина", + "Никон", "Анфиса", "Феликс", "Лия", "Иннокентий", "Роксана", "Всеволод", + "Эвелина", "Модест", "Юнона", "Трофим", "Изабелла", "Аполлон", "Глория", + "Касьян", "Аврора", "Любомир", "Адель", "Бронислав", "Доминика", "Афанасий", + "Фрида", "Евстафий", "Ассоль", "Венедикт", "Цветана", "Епифан", "Мелисса", + "Добрыня" +) + +_non_existent_names = [ + "Ноль", "Целковый", "Полушка", "Четвертушка", "Осьмушка", + "Пудовичок", "Медячок", "Серебрячок", "Золотничок", "Девятичок" +] +assert set(names_pool).isdisjoint(set(_non_existent_names)), \ +"В списке несуществующих имён существуют существующие имена сущностей" +names_pool_to_find = random.choices(names_pool, k=100) + _non_existent_names + +def generate_phone(phone_len=11) -> str: + # 88005553535 + return str(random.randint(10**phone_len, 10**(phone_len+1)-1)) + +def generate_test_data(N=10000, _sorted=False): + records = [] + for i in range(N): + name = random.choice(names_pool) + phone = generate_phone() + records.append((name, phone)) + + if _sorted: + return sorted(records) + return records \ No newline at end of file diff --git a/NeklyudovMS/task1/util/timeTester.py b/NeklyudovMS/task1/util/timeTester.py new file mode 100644 index 0000000..3e3204e --- /dev/null +++ b/NeklyudovMS/task1/util/timeTester.py @@ -0,0 +1,37 @@ +import time +import random +from typing import Callable, Any +from task1.util.randomNames import names_pool_to_find, names_pool + +def test(records: list, + insert_func: Callable[[Any, str, str], Any], + find_func: Callable[[Any, str], Any], + delete_func: Callable[[Any, str], Any]) -> dict: + data = None + + # Вставка всех записей + start = time.perf_counter() + for item in records: + data = insert_func(data, item[0], item[1]) + end = time.perf_counter() + insert_time = end - start + + # Поиск 110 случайных записей + start = time.perf_counter() + for name in names_pool_to_find: + find_func(data, name) + end = time.perf_counter() + find_time = end - start + + # Удаление 50 случайных записей + start = time.perf_counter() + for name in random.choices(names_pool, k = 50): + data = delete_func(data, name) + end = time.perf_counter() + delete_time = end - start + + return { + "insert_time" : insert_time , + "find_time" : find_time , + "delete_time": delete_time + } diff --git a/NeklyudovMS/task2/__init__.py b/NeklyudovMS/task2/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/NeklyudovMS/task2/consoleView.py b/NeklyudovMS/task2/consoleView.py new file mode 100644 index 0000000..404eeb2 --- /dev/null +++ b/NeklyudovMS/task2/consoleView.py @@ -0,0 +1,95 @@ +""" +Реализовать класс ConsoleView, который отображает лабиринт, +текущее положение игрока (если реализован пошаговый режим) и найденный путь. +Метод render(maze, player_position, path) рисует карту в консоли.""" + +import os + +from typing import Optional +from task2.mazeObjects.cell import Cell +from task2.mazeObjects.maze import Maze +from task2.mazeObjects.path import Path +from task2.observerSubject import MazeEvent, MazeEventType, Observer + +SBROS = "\033[0m" + +WALL = "#" +EXIT = "E" +START = "S" +PATH_SYMBOL = "+" +SPACE_SYMBOL = " " + +# Я убрал аргументы из render(), чтобы не передавать их при каждом запуске. +# И работать внутри класса приятнее, чем тянуть эти аргументы туда-сюда +class ConsoleView(Observer): + maze:Optional[Maze] + path:Optional[Path] + + def __init__(self, maze:Optional[Maze]=None, path:Optional[Path]=None): + super().__init__() + self.maze = maze + self.path = path + + def _getCellColored(self, cell:Cell) -> str: + if cell.isWall: + # Белый + return self._fmt_str(7, 7, WALL) + elif cell.isExit: + # Кислотно-зелёный + return self._fmt_str(12, 7, EXIT) + elif cell.isStart: + # Кислотно-красный + return self._fmt_str(9, 7, START) + elif self.path and self.path.array: + if cell in self.path.array: + # Градиент + percent = self.path.array.index(cell) / len(self.path.array) + n = self._ANSICalculator(*self._getGradient(percent)) + return self._fmt_str(n, 10, PATH_SYMBOL) + return SPACE_SYMBOL + + def _fmt_str(self, bg:int, fg:int, symbol:str) -> str: + return f"\033[48;5;{bg}m\033[38;5;{fg}m{symbol}{SBROS}" + + def _ANSICalculator(self, r:int, g:int, b:int): + r = max(0, min(5, r)) + g = max(0, min(5, g)) + b = max(0, min(5, b)) + return 16 + 36*r + 6*g + b + + def _getGradient(self, percent:float): + r = 5 * (1-percent) + g = 0 + b = 5 * percent + return int(round(r)), int(round(g)), int(round(b)) + + def render(self, player_position=None): + """ + Печатем ячейку. + Цвет зависит от индекса ячейчки в массиве path. + Если в массиве нет - просто белый. + """ + + os.system('cls' if os.name == 'nt' else 'clear') + + if not self.maze: + print("Лабиринт ещё не загружен") + return None + + output = "" + for y in range(self.maze.height): + for x in range(self.maze.width): + cell = self.maze.getCell(x, y) + output += self._getCellColored(cell) + output += "\n" + print(output) + + def update(self, event: MazeEvent): + if event.evtype in (MazeEventType.MAZE_LOADED, MazeEventType.PATH_FOUND, MazeEventType.MOVE): + if event.evtype == MazeEventType.PATH_FOUND: + if not event.data: raise ValueError + self.path = event.data + if event.evtype == MazeEventType.MAZE_LOADED: + if not event.data: raise ValueError + self.maze = self.maze + self.render() diff --git a/NeklyudovMS/task2/mazeBuilder.py b/NeklyudovMS/task2/mazeBuilder.py new file mode 100644 index 0000000..0d4c414 --- /dev/null +++ b/NeklyudovMS/task2/mazeBuilder.py @@ -0,0 +1,74 @@ +from abc import ABC, abstractmethod +from itertools import product +import sys +import os.path as path + +from task2.mazeObjects.maze import Maze +from task2.mazeObjects.cell import Cell +from task2.observerSubject import MazeEvent, MazeEventType, Subject + +class MazeBuilder(ABC): + """Интерфейс MazeBuilder с методом buildFromFile(filename)""" + @abstractmethod + def buildFromFile(self, filename: str): + """Создание лабиринта из файла.""" + +class TextFileMazeBuilder(MazeBuilder): + """Читает файл, парсит символы, + создаёт объекты Cell, + задаёт координаты и флаги, + после чего возвращает готовый Maze.""" + + start:dict + end:dict + + def _cellStrategy(self, letter: str) -> Cell: + if letter == '#': + return Cell(isWall=True) + elif letter == ' ': + return Cell() + elif letter == 'S': + return Cell(isStart=True) + elif letter == 'E': + return Cell(isExit=True) + else: + sys.stderr.write(f"Неизвестный символ '{letter}' при загрузке из файла\n") + return Cell() + + def _updateStartEnd(self, letter: str, x:int, y:int) -> None: + if letter == 'S': + self.start = {'x': x, 'y': y} + elif letter == 'E': + self.end = {'x': x, 'y': y} + + def _generate_row_from_txt(self, filename: str) -> list[str]: + with open(filename) as file: + text = file.read() + text = text.strip() + if not text: + raise ValueError(f"Файл \"{filename}\" пуст") + text = text.split('\n') + return text + + def buildFromFile(self, filename: str): + self.start = None + self.end = None + rows = self._generate_row_from_txt(filename) + height = len(rows) + width = len(rows[0]) + array = [[Cell() for j in range(width)] for i in range(height)] + + try: + for x, y in product(range(width), range(height)): + cell = self._cellStrategy(rows[y][x]) + self._updateStartEnd(rows[y][x], x, y) + cell.x = x + cell.y = y + array[y][x] = cell + except IndexError: + raise ValueError(f"В файле {filename}: Строка {y+1} имеет длину {len(rows[y])}, ожидалось {width}") + + maze_name, _ = path.splitext(path.basename(filename)) + + return Maze(array, self.start, self.end, name=maze_name) + \ No newline at end of file diff --git a/NeklyudovMS/task2/mazeExamples/100x100.txt b/NeklyudovMS/task2/mazeExamples/100x100.txt new file mode 100644 index 0000000..cadb849 --- /dev/null +++ b/NeklyudovMS/task2/mazeExamples/100x100.txt @@ -0,0 +1,100 @@ +S # # # # # # # # # # # # # # + # # ####### ### # ##### # # # # # # # # ### # # ### # # ### # ##### # ##### ### ### ### ######### # + # # # # # # # # # # # # # # # # # # # # # # # # # # + # ##### ##### ### ### ##### ##### ####### # ##### ####### # # # ####### ##### # ######### ### ### # + # # # # # # # # # # # # # # # # # # # # # # # # # + # # ##### # # ##### # # ####### # ### ##### # # # # ### ### ######### ##### # ##### # # ### ### # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + ##### # # # ### ### ####### # # ### ######### ### ### ### ### # # # # # ### ##### # # ### # # # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # + ### # ### # ##### ##### ######### ######### # ##### ### # ####### # ##### ### ####### # ### # ### # + # # # # # # # # # # # # # # # # # # # # # + # ################# # ### # # # # # ########### ############# # ##### ##### ##### # ##### ### # ### + # # # # # # # # # # # # # # # # # # # # # # + ### # ### # ### ####### # ##### ######### ### # ### ### # ####### # ### ####### ##### # ### # # # # + # # # # # # # # # # # # # # # # # # # # # # # + ######### ### ### # ### # ####### ##### # # # ####### ##### ####### # ########### ####### ######### + # # # # # # # # # # # # # # # # # # # # # +## # ####### ### ##### # ####### ### # # # # ##### ### ########### # # # ### # ##### # # ### ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # + ### # # ########### ######### # ### # # ### ### ####### ### # # # # ##### # ### ##### # # ### ### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # +## ##### # # # # # ### # ### ##### # # # ##### # ### # ### # # # # # # # ##### ### ####### # ### ### + # # # # # # # # # # # # # # # # # # # # # # # # # # # # + ##### ### # # # # # ######### ### ### ### # ##### ##### ### # ##### # ######### ############# ### # + # # # # # # # # # # # # # # # # # # # # # # # # + # ##### # # ### ### ##### # ### ### ##### # # ### # ##### ##### ### ### # ##### ### # # ### # # ### + # # # # # # # # # # # # # # # # # # # # # # # # # # + # # # ####### ####### ### ### ######### ### # # ##### # ### ########### ### # ### ####### ### # # # + # # # # # # # # # # # # # # # # # # # # # # + ################### # # # # ### # # # ######### # # ### ############### # ### ##### ### ### ##### # + # # # # # # # # # # # # # # # # # # # # # + ##### # # ### # # ### # ####### # # ##### # # ### ##### # ####### # # # ######### # ######### ##### + # # # # # # # # # # # # # # # # # # # # # # # # # # # # +#### # # ### # # ### # ### ####### ##### # # ### # # ##### # # ####### # # # ##### ### # # ####### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +## # # # # ### ### # ### ### # # # ### # ####### ### # ########### # ##### ##### # # ### ### ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # # + ########### # # ########### ### # # # # # ### # # ### # ####### # ######### # # ### # ######### ### + # # # # # # # # # # # # # # # # # # # # # # # # +######## # # # ### # ########### # # ####### ### # # # ####### ### # # # ### # ### ######### # # # # + # # # # # # # # # # # # # # # # # # # # # # # + ##### ##### ### # # # ####### ### ### # # # # ############# # ##### # ### ##### ######### ### ### # + # # # # # # # # # # # # # # # # # # # # # # # # # + ### ### # ### # ##### # # # ### # # # ### # ### ### # # # # ########### ####### # ##### ####### ### + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +## ####### # ##### # ### ### # # # # # # # ####### ### # # # # # # # # ### # # ##### # # # # ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + ### # # # ##### ####### # ### # ### ### ####### # # ### ####### ### ####### # ### ####### # # # # # + # # # # # # # # # # # # # # # # # # # # # # # # + # ##### ##### # # ### ### # ######### ### ### ### ### ####### ##### # ######### ##### # ### # ### # + # # # # # # # # # # # # # # # # # # # # # # # # # + # # ####### # ##### ### # # # # # ### ### # ### ### ######### # ####### # ####### ### ######### ### + # # # # # # # # # # # # # # # # # # # # # # # # # # # + ######### # ### ### # # # # # # ####### ##### ### # # ##### # ### # # ####### # # # ### # # # # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # +## # # # ### ##### # ######### # # ####### ### ### # ##### ######### # # # ####### ### # # # # ### # + # # # # # # # # # # # # # # # # # # # # # # # + ### ######### ####### # # ######### # # ### ### ### ##### ### # ########### ######### # # # ### ### + # # # # # # # # # # # # # # # # # # # # # # # # +## ######### # ### # ####### ### # ### ### # # ####### # ### ##### ### # # ### # ### ##### # # ### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # # ### ### ### # # # ##### # ### # ### ### # # # ####### ##### ### ### # ##### # ##### # ### # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # # # ### ### # ### # ######### # ######### # ### # # # ### ##### ### # ### # # ### # ##### ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # # + ##### # ### ##### ####### ### # ##### # # # ### ### # ##### # # ### # ####### ##### # # # ### # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # + ### # ### ######### # ##### ### # ### # # # ############# ### ### # ##### # ### ######### # ### # # + # # # # # # # # # # # # # # # # # # # # # # # # +## # # # ### ##### # ##### # ### ### # # # ### # # ######### # # ##### ### ####### ### # ######### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # + # ############### ### ####### ### # ### ####### # # # # ######### # ### # # # ##### ##### # # ##### + # # # # # # # # # # # # # # # # # # # # # # + ##### # # ### # ### ######### # ######### # # ### # # ####### # ########### # # # ##### ####### # # + # # # # # # # # # # # # # # # # # # # # # # # +## # ####### ### # # # ############# ### ### ### ### ##### # # ### ########### ##### # ### ### # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # + ### ### # # # ##### ### # # ##### ####### # # ### ### # # ##### # # ####### ##### # # # # # ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # +###### ##### ### # ### ### # # ########### # # # ##### # ### ##### # # ### ######### ### ##### # ### + # # # # # # # # # # # # # # # # # # # # # # # + # # # # # ### ####### ######### # # ######### ### # ##### ##### ##### ### # # # # # # ### ####### # + # # # # # # # # # # # # # # # # # # # # # # # # +#### # ##### # # # ##### ### # ### # ##### ### # ##### ### ######### ### ### ########### # # ##### # + # # # # # # # # # # # # # # # # # # # # # # # # # # # + ######### ##### # ####### # # # ##### # ### # # # # ####### ##### # # ### ### # # # # ### # # ### # + # # # # # # # # # # # # # # # # # # # # # # # # # # + # ### # ##### # # # ############### ### ######### ### # ##### # # ######### # ### # ### # # # # ### + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # # # ####### # ### # ##### ##### # # ### # ### # # ##### # ### # # # ####### # ##### # # # ### # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # + ##### # ### # # # ##### ##### # # # ### ### # # # # ######### # ########### # # ##### ####### # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # +## # # # # ##### # ### ####### ########### ### # # ####### # # ##### # # # ### ##### ##### # ##### # + # # # # # # # # # # # # # # # # # # # # # # + ### ##### ########### # ### # # ####### # # # ############# # ### ### # ### ######### # ### ### # # + # # # # # # # # # # # # # # # # # # # # # # # # # + ##### # # # ##### ####### # ### # # ##### # ### ####### ######### # ########### ### # ######### # # + # # # # # # # # # +################################################################################################## E diff --git a/NeklyudovMS/task2/mazeExamples/10x10.txt b/NeklyudovMS/task2/mazeExamples/10x10.txt new file mode 100644 index 0000000..3633a55 --- /dev/null +++ b/NeklyudovMS/task2/mazeExamples/10x10.txt @@ -0,0 +1,10 @@ +S # + ### ### # + # # # +## # # ### + # # # + ####### # + # # +## # ##### + +######## E diff --git a/NeklyudovMS/task2/mazeExamples/25x25.txt b/NeklyudovMS/task2/mazeExamples/25x25.txt new file mode 100644 index 0000000..dbe4af8 --- /dev/null +++ b/NeklyudovMS/task2/mazeExamples/25x25.txt @@ -0,0 +1,25 @@ +S # # # + # ##### # # # ####### # + # # # # # # +#### # ##### # # ####### + # # # # # # # +## # # # ##### ### # # # + # # # # # # # # # + ### # # # # ### # # # # + # # # # # # # # + # ### # # ### ### # #### + # # # # # # # + ### # # # ####### ##### + # # # # + # ################# ### + # # # # + # # # ####### ####### ## + # # # # # + ### ##### # ### ### ### + # # # # # # + # # # ##### # # ####### + # # # # # # + ##### # ####### # ### ## + # # # # # # # +#### # # # ### ##### # # + # # # E diff --git a/NeklyudovMS/task2/mazeExamples/50x50.txt b/NeklyudovMS/task2/mazeExamples/50x50.txt new file mode 100644 index 0000000..bdbcf62 --- /dev/null +++ b/NeklyudovMS/task2/mazeExamples/50x50.txt @@ -0,0 +1,50 @@ +S # # # # # # # + ### # ##### # ### ### # # ### # # ### # ### # # # + # # # # # # # # # # # # # # # + ####### # # ####### ##### # ##### ####### ### ### + # # # # # # # # # # + ### # ##### ### # ### # # ##### # ############# # + # # # # # # # # # # # # # + # ### # # ### ############# # # ##### ##### # # # + # # # # # # # # # # # # # # +#### ##### # ### # ##### # # ##### # ### # ##### # + # # # # # # # # # # # # + ### ####### ####### # ####### # ##### # ### ### # + # # # # # # # # # # # # + ####### # # # ### ##### # ##### ### # ### ####### + # # # # # # # # # # # # # +## ### ####### ### # # ### # # # # ### # ### ### # + # # # # # # # # # # # # + ####### # ##### ####### ### ######### ##### ### # + # # # # # # # # # # # +#### # # ### ##### ####### # # # ### # # # ### # # + # # # # # # # # # # # # # # # # + # # # ### # # # # # # ### ####### # ##### # ### # + # # # # # # # # # # # # # # # # + # # # ### ######### # # ### # # # ##### # # # ### + # # # # # # # # # # # # # + ####### ### # ### ####### # # ##### # ######### # + # # # # # # # # # # # # # + ########### ### ### ### # ### # # ##### # ### # # + # # # # # # # # # # # # # # + ### # ### ### ####### ### # ### # # # ####### # # + # # # # # # # # # # # # # # # # +## # ### # # ### # # # # # # # # # ### # ### ### # + # # # # # # # # # # # # # # # # # # + ##### # # ##### # # # ####### # ### # # # ### # # + # # # # # # # # # # # # # # # + # # # ### # ### ########### # ##### # ### # # ### + # # # # # # # # # # # # # +#### ##### # # ### ### # ##### # ##### # ######### + # # # # # # # # # # # + # ### ##### ### ### # ### ########### ######### # + # # # # # # # # # # + ### # ##### # # ##### # ####### # ### ### # ##### + # # # # # # # # # # # +## ##### # ### ### # ##### ####### # # ######### # + # # # # # # # # # # # # + ### # ##### # # ##### # ### ##### ##### ####### # + # # # # # # # # # # # + # ########### ########### ##### ####### # ### # # + # # # # +################################################ E diff --git a/NeklyudovMS/task2/mazeExamples/5x5.txt b/NeklyudovMS/task2/mazeExamples/5x5.txt new file mode 100644 index 0000000..28f1058 --- /dev/null +++ b/NeklyudovMS/task2/mazeExamples/5x5.txt @@ -0,0 +1,5 @@ +##### +# S # +# ### +# E +##### \ No newline at end of file diff --git a/NeklyudovMS/task2/mazeExamplesSpeical/maze_25x25_empty.txt b/NeklyudovMS/task2/mazeExamplesSpeical/maze_25x25_empty.txt new file mode 100644 index 0000000..7f7dfce --- /dev/null +++ b/NeklyudovMS/task2/mazeExamplesSpeical/maze_25x25_empty.txt @@ -0,0 +1,25 @@ +S + + + + + + + + + + + + + + + + + + + + + + + + E diff --git a/NeklyudovMS/task2/mazeExamplesSpeical/maze_25x25_wo_exit.txt b/NeklyudovMS/task2/mazeExamplesSpeical/maze_25x25_wo_exit.txt new file mode 100644 index 0000000..b977d12 --- /dev/null +++ b/NeklyudovMS/task2/mazeExamplesSpeical/maze_25x25_wo_exit.txt @@ -0,0 +1,25 @@ +S # # # + # ##### # # # ####### # + # # # # # # +#### # ##### # # ####### + # # # # # # # +## # # # ##### ### # # # + # # # # # # # # # + ### # # # # ### # # # # + # # # # # # # # + # ### # # ### ### # #### + # # # # # # # + ### # # # ####### ##### + # # # # + # ################# ### + # # # # + # # # ####### ####### ## + # # # # # + ### ##### # ### ### ### + # # # # # # + # # # ##### # # ####### + # # # # # # + ##### # ####### # ### ## + # # # # # # # +#### # # # ### ##### # # + # # # # diff --git a/NeklyudovMS/task2/mazeObjects/__init__.py b/NeklyudovMS/task2/mazeObjects/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/NeklyudovMS/task2/mazeObjects/cell.py b/NeklyudovMS/task2/mazeObjects/cell.py new file mode 100644 index 0000000..9d617ab --- /dev/null +++ b/NeklyudovMS/task2/mazeObjects/cell.py @@ -0,0 +1,13 @@ +class Cell: + """Хранит координаты (x, y) + флаги isWall, isStart, isExit + метод isPassable() (возвращает True для прохода, если не стена).""" + def __init__(self, x: int = 0, y: int = 0, isWall:bool = False, isStart:bool = False, isExit:bool = False): + self.x = x + self.y = y + self.isWall = isWall + self.isStart = isStart + self.isExit = isExit + + def isPassable(self): + return not self.isWall diff --git a/NeklyudovMS/task2/mazeObjects/maze.py b/NeklyudovMS/task2/mazeObjects/maze.py new file mode 100644 index 0000000..dce78b6 --- /dev/null +++ b/NeklyudovMS/task2/mazeObjects/maze.py @@ -0,0 +1,41 @@ +from task2.mazeObjects.cell import Cell + +class Maze: + """Хранит двумерный массив клеток, + ширину, высоту, ссылки на стартовую и выходную клетку. + Методы: + getCell(x, y), getNeighbors(cell) – возвращает список соседних проходимых клеток + (вверх, вниз, влево, вправо, если в пределах границ и не стена).""" + + def __init__(self, mazeArray: list[list[Cell]], start: dict, end: dict, name:str="") -> None: + self.mazeArray = mazeArray + self.height = len(mazeArray) # X + self.width = len(mazeArray[0]) # Y + + self.startCell = self.getCell(start['x'], start['y']) if start else None + self.endCell = self.getCell(end['x'], end['y']) if end else None + self.name = name + + def getCell(self, x: int, y: int): + return self.mazeArray[y][x] + + def checkCell(self, x: int, y: int): + if not(0 <= x and x < self.width): + return False + if not(0 <= y and y < self.height): + return False + return self.getCell(x, y).isPassable() + + def getNeighbors(self, cell: Cell): + point = (cell.x, cell.y) + offsets = ((0, 1), + (0, -1), + (-1, 0), + (1, 0)) + passableCells = [] + for ofst in offsets: + x = point[0]+ofst[0] + y = point[1]+ofst[1] + if self.checkCell(x, y): + passableCells.append(self.getCell(x, y)) + return passableCells \ No newline at end of file diff --git a/NeklyudovMS/task2/mazeObjects/path.py b/NeklyudovMS/task2/mazeObjects/path.py new file mode 100644 index 0000000..973aa89 --- /dev/null +++ b/NeklyudovMS/task2/mazeObjects/path.py @@ -0,0 +1,7 @@ +from typing import Optional +from task2.mazeObjects.cell import Cell + +class Path: + def __init__(self, array:Optional[list[Cell]], visited_cells:int): + self.array = array + self.visited_cells = visited_cells \ No newline at end of file diff --git a/NeklyudovMS/task2/mazeSolver.py b/NeklyudovMS/task2/mazeSolver.py new file mode 100644 index 0000000..cd7000b --- /dev/null +++ b/NeklyudovMS/task2/mazeSolver.py @@ -0,0 +1,70 @@ +from typing import Optional +from task2.mazeObjects.maze import Maze +from task2.mazeObjects.cell import Cell +from task2.observerSubject import MazeEvent, MazeEventType, Subject +from task2.strategyObjects.pathFindingStrategy import PathFindingStrategy +from task2.strategyObjects.BFS import BFS + + +import time + +class SearchStats: + maze_name:str = "None" + """Время выполнения в миллисекундах, количество посещённых клеток, длина найденного пути""" + def __init__(self, path: Optional[list[Cell]], duration:float, visited_cells:int, path_len:int, strategy_name:str): + self.duration = duration + self.visited_cells = visited_cells + self.path_len = path_len + self.path = path + self.strategy_name = strategy_name + + def toDict(self,): + return { + "strategy_name" : self.strategy_name, + "maze_name" : self.maze_name, + "duration" : self.duration, + "visited_cells" : self.visited_cells, + "path_len" : self.path_len + } + +class MazeSolver(Subject): + """ + MazeSolver содержит поля maze и strategy. + Метод setStrategy(strategy) для динамической смены алгоритма. + Метод solve() вызывает strategy.findPath(...) и возвращает объект SearchStats (время выполнения в миллисекундах, + количество посещённых клеток, длина найденного пути). + Для замера времени используйте time.perf_counter() до и после вызова стратегии. + """ + + def __init__(self, strategy:PathFindingStrategy, maze:Optional[Maze]=None): + super().__init__() + self._maze = maze + self.strategy = strategy + + def setMaze(self, maze: Optional[Maze]): + self._maze = maze + self.notify(MazeEvent(MazeEventType.MAZE_LOADED, data=maze)) + + def setStrategy(self, strategy:PathFindingStrategy): + self.strategy = strategy + + def getStrategyName(self): + return self.strategy.__class__.__name__ + + def solve(self): + if not self._maze: + raise ValueError + + if not self._maze.startCell or not self._maze.endCell: + return SearchStats(None, 0.0, 0, -1, self.getStrategyName()) + + t_start = time.perf_counter() + path = self.strategy.findPath(self._maze, self._maze.startCell, self._maze.endCell) + duration = (time.perf_counter() - t_start) * 1000 + + path_len = len(path.array) if path.array else -1 + strategy_name = self.getStrategyName() + + stats = SearchStats(path.array, duration, path.visited_cells, path_len, strategy_name) + self.notify(MazeEvent(MazeEventType.PATH_FOUND, data=path)) + return stats \ No newline at end of file diff --git a/NeklyudovMS/task2/observerSubject.py b/NeklyudovMS/task2/observerSubject.py new file mode 100644 index 0000000..c49b8f8 --- /dev/null +++ b/NeklyudovMS/task2/observerSubject.py @@ -0,0 +1,43 @@ +""" +Создать интерфейс Observer с методом update(event), +где event может быть строкой или объектом с типом события ("path_found", "move", "maze_loaded"). +""" + +from enum import Enum +from abc import ABC, abstractmethod + +class MazeEventType(Enum): + PATH_FOUND = "path_found" + MOVE = "move" + MAZE_LOADED = "maze_loaded" + +class MazeEvent: + data=None + def __init__(self, evtype: MazeEventType, data=None): + if not isinstance(evtype, MazeEventType): + raise TypeError(f"evtype must be an EventType, got {type(evtype)}") + self.evtype = evtype + self.data = data + +class Observer(ABC): + @abstractmethod + def update(self, event: MazeEvent): + raise NotImplementedError + + +class Subject(ABC): + """Издатель: управляет подписчиками и отправляет им уведомления.""" + def __init__(self): + self._observers:set[Observer] = set() + + def attach(self, obs:Observer): + "Подписать наблюдателя" + self._observers.add(obs) + + def detach(self, obs:Observer): + "Отписать наблюдателя" + self._observers.discard(obs) + + def notify(self, event:MazeEvent): + for obs in self._observers: + obs.update(event) \ No newline at end of file diff --git a/NeklyudovMS/task2/strategyObjects/AStar.py b/NeklyudovMS/task2/strategyObjects/AStar.py new file mode 100644 index 0000000..1afad68 --- /dev/null +++ b/NeklyudovMS/task2/strategyObjects/AStar.py @@ -0,0 +1,47 @@ +import heapq +from itertools import count +from typing import Optional + +from task2.strategyObjects.pathFindingStrategy import PathFindingStrategy +from task2.strategyObjects.util import restorePath + +from task2.mazeObjects.maze import Maze +from task2.mazeObjects.cell import Cell +from task2.mazeObjects.path import Path + +class AStar(PathFindingStrategy): + """Алгоритм с эвристикой (etc. манхэттенское расстояние) – компромисс между скоростью и оптимальностью.""" + def heuristic(self, first: Cell, second: Cell) -> int: + return abs(first.x - second.x) + abs(first.y - second.y) + + def findPath(self, maze: Maze, start: Cell, exit: Cell) -> Path: + tie_breaker = count() + start_heuristic = self.heuristic(start, exit) + heap: list[tuple[int, int, int, Cell]] = [ + (start_heuristic, start_heuristic, next(tie_breaker), start) + ] + g_score: dict[Cell, int] = {start: 0} + parents: dict[Cell, Optional[Cell]] = {start: None} + visited: set[Cell] = set() + + while heap: + _, _, _, current = heapq.heappop(heap) + if current in visited: + continue + visited.add(current) + + if current.isExit: + return Path(restorePath(parents, exit), len(visited)) + + for neighbor in maze.getNeighbors(current): + tentative_score = g_score[current] + if tentative_score < g_score.get(neighbor, 10**12): + g_score[neighbor] = tentative_score + parents[neighbor] = current + heuristic = self.heuristic(neighbor, exit) + priority = tentative_score + heuristic + heapq.heappush( + heap, + (priority, heuristic, next(tie_breaker), neighbor), + ) + return Path(None, len(visited)) \ No newline at end of file diff --git a/NeklyudovMS/task2/strategyObjects/BFS.py b/NeklyudovMS/task2/strategyObjects/BFS.py new file mode 100644 index 0000000..859897c --- /dev/null +++ b/NeklyudovMS/task2/strategyObjects/BFS.py @@ -0,0 +1,43 @@ +from task2.strategyObjects.pathFindingStrategy import PathFindingStrategy +from task2.strategyObjects.util import restorePath + +from task2.mazeObjects.maze import Maze +from task2.mazeObjects.cell import Cell +from task2.mazeObjects.path import Path + +import queue + +class BFS(PathFindingStrategy): + """Поиск в ширину – гарантирует кратчайший путь по количеству шагов. + Возвращает None, если пути нет""" + def findPath(self, maze: Maze, start: Cell, exit: Cell) -> Path: + visited = dict() + parents = dict() + q = queue.Queue() + + q.put(start) + visited[start] = 0 + parents[start] = None + + found_exit = False + while not q.empty(): + current = q.get() + + # Условие нахождение выхода + if current.isExit: + found_exit = True + break + + # Перебор соседей + for hood in maze.getNeighbors(current): + if hood in visited: + continue + visited[hood] = visited[current] + 1 + parents[hood] = current + q.put(hood) + + if not found_exit: + path_list = None + else: + path_list = restorePath(parents, exit) + return Path(path_list, len(visited)) \ No newline at end of file diff --git a/NeklyudovMS/task2/strategyObjects/DFS.py b/NeklyudovMS/task2/strategyObjects/DFS.py new file mode 100644 index 0000000..31d02eb --- /dev/null +++ b/NeklyudovMS/task2/strategyObjects/DFS.py @@ -0,0 +1,41 @@ +from task2.strategyObjects.pathFindingStrategy import PathFindingStrategy +from task2.strategyObjects.util import restorePath + +from task2.mazeObjects.maze import Maze +from task2.mazeObjects.cell import Cell +from task2.mazeObjects.path import Path + +class DFS(PathFindingStrategy): + """Поиск в глубину – быстрый, но не обязательно кратчайший. + Возвращает None, если пути нет""" + def findPath(self, maze: Maze, start: Cell, exit: Cell) -> Path: + visited = dict() + parents = dict() + stack = [] + + stack.append(start) + visited[start] = 0 + parents[start] = None + + found_exit = False + while stack: + current = stack.pop() + + # Условие нахождение выхода + if current.isExit: + found_exit = True + break + + # Перебор соседей + for hood in maze.getNeighbors(current): + if hood in visited: + continue + visited[hood] = visited[current] + 1 + parents[hood] = current + stack.append(hood) + + if not found_exit: + path_list = None + else: + path_list = restorePath(parents, exit) + return Path(path_list, len(visited)) \ No newline at end of file diff --git a/NeklyudovMS/task2/strategyObjects/__init__.py b/NeklyudovMS/task2/strategyObjects/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/NeklyudovMS/task2/strategyObjects/pathFindingStrategy.py b/NeklyudovMS/task2/strategyObjects/pathFindingStrategy.py new file mode 100644 index 0000000..9417065 --- /dev/null +++ b/NeklyudovMS/task2/strategyObjects/pathFindingStrategy.py @@ -0,0 +1,14 @@ +from abc import ABC, abstractmethod + +from task2.mazeObjects.maze import Maze +from task2.mazeObjects.cell import Cell +from task2.mazeObjects.path import Path + +class PathFindingStrategy(ABC): + """Интерфейс PathFindingStrategy с методом findPath(maze, start, exit), + возвращающим список клеток пути (от старта до выхода включительно) или пустой список, если пути нет.""" + + @abstractmethod + def findPath(self, maze: Maze, start: Cell, exit: Cell) -> Path: + """Возвращает список клеток пути от старта до выхода включительно. Пути нет - пустой список.""" + raise NotImplementedError \ No newline at end of file diff --git a/NeklyudovMS/task2/strategyObjects/util.py b/NeklyudovMS/task2/strategyObjects/util.py new file mode 100644 index 0000000..d734cdb --- /dev/null +++ b/NeklyudovMS/task2/strategyObjects/util.py @@ -0,0 +1,13 @@ +from typing import Optional +from task2.mazeObjects.maze import Maze +from task2.mazeObjects.cell import Cell + +def restorePath(parents: dict, exit: Cell) -> Optional[list[Cell]]: + path = [] + current = exit + while current: + path.append(current) + if current not in parents: + return None + current = parents[current] + return path[::-1] \ No newline at end of file diff --git a/NeklyudovMS/task2/tester.py b/NeklyudovMS/task2/tester.py new file mode 100644 index 0000000..6e56a5f --- /dev/null +++ b/NeklyudovMS/task2/tester.py @@ -0,0 +1,84 @@ +from task2.mazeBuilder import MazeBuilder +from task2.mazeObjects.maze import Maze +from task2.mazeSolver import MazeSolver, SearchStats + +from task2.strategyObjects.BFS import BFS +from task2.strategyObjects.DFS import DFS +from task2.strategyObjects.AStar import AStar + +import csv +import os + +TEST_ITERATIONS = 10 + +class Tester(): + """Для каждого лабиринта и каждой стратегии запустить solve() 5–10 раз, + усреднить время, количество посещённых клеток, длину пути. + Записать результаты в CSV: + лабиринт,стратегия,время_мс,посещено_клеток,длина_пути.""" + result:list[SearchStats] + def __init__(self, builder:MazeBuilder, writefile:str): + self._builder = builder + self.writefile = "../" + writefile + + def setTestingDirectory(self, directory:str): + if directory[-1] != "/": + directory += "/" + self._directory = "../" + directory + + def _getMazes(self) -> list[Maze]: + arr = [] + files = os.listdir(self._directory) + only_txt_files = [f for f in files if os.path.isfile(os.path.join(self._directory, f)) and os.path.splitext(f)[1] == ".txt"] + + for f in only_txt_files: + arr.append(self._builder.buildFromFile(os.path.join(self._directory, f))) + return arr + + def _solveAvg(self, solver: MazeSolver): + avgtime = 0 + for i in range(TEST_ITERATIONS): + result = solver.solve() + # Всё кроме времени будет одинаковым + avgtime += result.duration/TEST_ITERATIONS + result.duration = avgtime + return result + + def saveCSV(self): + rows = [] + for r in self.result: + r = r.toDict() + row = (r["strategy_name"], + r["maze_name"], + r["duration"], + r["visited_cells"], + r["path_len"] + ) + rows.append(row) + with open(self.writefile, "w", newline="") as f: + writer = csv.writer(f) + writer.writerow(["Алгоритм", "Лабиринт", "Время (мс)", "Посещённые клетки", "Длинна пути"]) + writer.writerows(rows) + + def test(self): + self.result = [] + arr = self._getMazes() + for algoritm in (BFS, DFS, AStar): + solver = MazeSolver(algoritm()) # это прикол + for maze in arr: + solver.setMaze(maze) + self.result.append(self._solveAvg(solver)) + self.result[-1].maze_name = maze.name + return self.result + + +if __name__ == "__main__": + exit() + from task2.mazeBuilder import TextFileMazeBuilder + + builder = TextFileMazeBuilder() + tester = Tester(builder, "docs/data/task2/results.csv") + tester.setTestingDirectory("task2/mazeExamples") + tester.test() + tester.saveCSV() + \ No newline at end of file