From 58d0447aae6ebf6cef7416ec7fd53f76792ce918 Mon Sep 17 00:00:00 2001 From: PaulVA Date: Sat, 5 Sep 2026 13:51:05 +0300 Subject: [PATCH 1/3] [0] initial commit --- PaulVA/429 | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 PaulVA/429 diff --git a/PaulVA/429 b/PaulVA/429 new file mode 100644 index 0000000..e69de29 From c12f9ef1bfd61d0d863095e94459bca519cf7bd8 Mon Sep 17 00:00:00 2001 From: PaulVA Date: Sat, 5 Sep 2026 19:09:46 +0300 Subject: [PATCH 2/3] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=BB=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=BD=D1=8B=D0=B5=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B?= =?UTF-8?q?=201=20=D0=B8=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lab1/docs/data/graph_delete.png | Bin 0 -> 13209 bytes lab1/docs/data/graph_find.png | Bin 0 -> 13059 bytes lab1/docs/data/graph_insert.png | Bin 0 -> 13179 bytes lab1/docs/data/results.csv | 19 +++ lab1/docs/report.md | 34 ++++ lab1/experiments.py | 185 +++++++++++++++++++++ lab1/graphs.py | 56 +++++++ lab1/phonebook.py | 211 ++++++++++++++++++++++++ lab2/docs/data/dead_time.png | Bin 0 -> 15603 bytes lab2/docs/data/empty_time.png | Bin 0 -> 12802 bytes lab2/docs/data/large_time.png | Bin 0 -> 15034 bytes lab2/docs/data/noexit_time.png | Bin 0 -> 15898 bytes lab2/docs/data/results.csv | 16 ++ lab2/docs/data/simple_time.png | Bin 0 -> 15906 bytes lab2/docs/report.md | 212 ++++++++++++++++++++++++ lab2/experiments.py | 93 +++++++++++ lab2/graphs.py | 23 +++ lab2/make_large.py | 26 +++ lab2/maze_solver.py | 284 ++++++++++++++++++++++++++++++++ lab2/mazes/dead.txt | 20 +++ lab2/mazes/empty.txt | 50 ++++++ lab2/mazes/large.txt | 100 +++++++++++ lab2/mazes/noexit.txt | 10 ++ lab2/mazes/simple.txt | 5 + 24 files changed, 1344 insertions(+) create mode 100644 lab1/docs/data/graph_delete.png create mode 100644 lab1/docs/data/graph_find.png create mode 100644 lab1/docs/data/graph_insert.png create mode 100644 lab1/docs/data/results.csv create mode 100644 lab1/docs/report.md create mode 100644 lab1/experiments.py create mode 100644 lab1/graphs.py create mode 100644 lab1/phonebook.py create mode 100644 lab2/docs/data/dead_time.png create mode 100644 lab2/docs/data/empty_time.png create mode 100644 lab2/docs/data/large_time.png create mode 100644 lab2/docs/data/noexit_time.png create mode 100644 lab2/docs/data/results.csv create mode 100644 lab2/docs/data/simple_time.png create mode 100644 lab2/docs/report.md create mode 100644 lab2/experiments.py create mode 100644 lab2/graphs.py create mode 100644 lab2/make_large.py create mode 100644 lab2/maze_solver.py create mode 100644 lab2/mazes/dead.txt create mode 100644 lab2/mazes/empty.txt create mode 100644 lab2/mazes/large.txt create mode 100644 lab2/mazes/noexit.txt create mode 100644 lab2/mazes/simple.txt diff --git a/lab1/docs/data/graph_delete.png b/lab1/docs/data/graph_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..542ee28505c712b57f48b657debe07bff3fea47e GIT binary patch literal 13209 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 current['name']: + if current['right'] is None: + current['right'] = new_node + break + current = current['right'] + + else: + current['phone'] = phone + break + + return root + +def bst_find(root, name): + current = root + + while current is not None: + if name == current['name']: + return current['phone'] + + if name < current['name']: + current = current['left'] + else: + current = current['right'] + + return None + +def bst_delete(root, name): + parent = None + current = root + + while current is not None and current['name'] != name: + parent = current + + if name < current['name']: + current = current['left'] + else: + current = current['right'] + + if current is None: + return root + + if current['left'] is None: + child = current['right'] + + elif current['right'] is None: + child = current['left'] + + else: + successor_parent = current + successor = current['right'] + + while successor['left'] is not None: + successor_parent = successor + successor = successor['left'] + + current['name'] = successor['name'] + current['phone'] = successor['phone'] + + if successor_parent['left'] == successor: + successor_parent['left'] = successor['right'] + else: + successor_parent['right'] = successor['right'] + + return root + + if parent is None: + return child + + if parent['left'] == current: + parent['left'] = child + else: + parent['right'] = child + + return root + +def bst_list_all(root): + records = [] + + def inorder(node): + if node is None: + return + + inorder(node['left']) + records.append((node['name'], node['phone'])) + inorder(node['right']) + + inorder(root) + + return records \ No newline at end of file diff --git a/lab2/docs/data/dead_time.png b/lab2/docs/data/dead_time.png new file mode 100644 index 0000000000000000000000000000000000000000..d440812f2656762eae43e6dbb68684753fb555e9 GIT binary patch literal 15603 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 literal 0 HcmV?d00001 diff --git a/lab2/docs/data/empty_time.png b/lab2/docs/data/empty_time.png new file mode 100644 index 0000000000000000000000000000000000000000..573b627b0883d0c50af9be2bdc92ea75863ecc7a GIT binary patch literal 12802 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 literal 0 HcmV?d00001 diff --git a/lab2/docs/data/large_time.png b/lab2/docs/data/large_time.png new file mode 100644 index 0000000000000000000000000000000000000000..6d99e6577aa24c5dc5585becb5265c0f857af940 GIT binary patch literal 15034 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 E0RXdsb^rhX literal 0 HcmV?d00001 diff --git a/lab2/docs/data/noexit_time.png b/lab2/docs/data/noexit_time.png new file mode 100644 index 0000000000000000000000000000000000000000..8ac5ef66631d05e6b10d5536b70c20f6d89870cf GIT binary patch literal 15898 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 a_sG0WCu3&5`9FpmAd1)2Wp*&7^96=CDIoZ1^ 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 literal 0 HcmV?d00001 diff --git a/lab2/docs/report.md b/lab2/docs/report.md new file mode 100644 index 0000000..bb0e596 --- /dev/null +++ b/lab2/docs/report.md @@ -0,0 +1,212 @@ +Лабораторная работа 2 + +Поиск выхода из лабиринта + +Цель работы +----------- +Цель работы состоит в реализации программы для поиска выхода из лабиринта с использованием объектно ориентированного подхода и паттернов проектирования + +В программе реализована загрузка лабиринта из файла несколько алгоритмов поиска и сравнение их работы + +Структура программы +------------------- +В программе используются классы Cell для отдельной клетки лабиринта и Maze для самого лабиринта + +Для загрузки используется MazeBuilder и его реализация TextFileMazeBuilder + +Для поиска пути используется общий класс PathFindingStrategy и три алгоритма BFSStrategy DFSStrategy и AStarStrategy + +За хранение результатов отвечает SearchStats а запуск поиска выполняет MazeSolver + +Для вывода информации используются Observer и ConsoleView + +Использованные паттерны +----------------------- +В работе использованы три паттерна Builder Strategy и Observer + +Builder используется для загрузки лабиринта из текстового файла + +TextFileMazeBuilder читает файл и создаёт объект Maze + +В файле символ # обозначает стену пробел обозначает свободную клетку S является началом а E выходом + +Использование Builder позволяет отдельно реализовать загрузку лабиринта и сам класс лабиринта + +Strategy используется для выбора алгоритма поиска + +В программе реализованы BFS DFS и A* + +Все алгоритмы имеют общий интерфейс PathFindingStrategy поэтому в MazeSolver можно менять алгоритм без изменения самого решателя + +Observer используется для вывода информации о поиске + +MazeSolver отправляет события а ConsoleView получает их и выводит информацию в консоль + +Таким образом вывод отделён от основной логики поиска + +Алгоритмы поиска +---------------- +BFS использует очередь и при обычных условиях находит кратчайший путь в лабиринте без весов + +DFS использует стек и может найти путь быстрее но найденный путь не обязательно будет кратчайшим + +A* использует очередь с приоритетом и манхэттенскую эвристику поэтому старается в первую очередь проверять клетки которые находятся ближе к выходу + +Схема классов +------------- +classDiagram + +class Cell { + x + y + is_wall + is_start + is_exit + is_passable() +} + +class Maze { + width + height + cells + start + exit + get_cell() + get_neighbors() +} + +class MazeBuilder { + build_from_file() +} + +class TextFileMazeBuilder { + build_from_file() +} + +class PathFindingStrategy { + find_path() +} + +class BFSStrategy { + find_path() +} + +class DFSStrategy { + find_path() +} + +class AStarStrategy { + find_path() +} + +class SearchStats { + path + time_ms + visited_count + path_length +} + +class MazeSolver { + maze + strategy + set_strategy() + solve() +} + +class Observer { + update() +} + +class ConsoleView { + update() +} + +MazeBuilder <|-- TextFileMazeBuilder +PathFindingStrategy <|-- BFSStrategy +PathFindingStrategy <|-- DFSStrategy +PathFindingStrategy <|-- AStarStrategy +Observer <|-- ConsoleView +MazeSolver --> Maze +MazeSolver --> PathFindingStrategy +MazeSolver --> Observer +Maze --> Cell +Тестирование +------------ +Для проверки использовалось пять разных лабиринтов + +simple.txt представляет простой лабиринт dead.txt содержит тупики large.txt является большим запутанным лабиринтом empty.txt не содержит стен а в noexit.txt выход недостижим + +Каждый алгоритм запускался пять раз + +Во время эксперимента измерялось время поиска количество посещённых клеток и длина найденного пути + +Результаты сохранялись в файл results.csv + +Результаты +---------- +simple.txt +Алгоритм Время мс Посещено Путь +BFS 0.01464 11 6 +DFS 0.01018 9 8 +A* 0.01774 9 6 + +Все алгоритмы работают быстро + +BFS и A* нашли более короткий путь чем DFS + +dead.txt +Алгоритм Время мс Посещено Путь +BFS 0.36430 307 35 +DFS 0.23494 279 151 +A* 0.38374 235 35 + +DFS работал немного быстрее но нашёл более длинный путь + +BFS и A* нашли короткий путь + +large.txt +Алгоритм Время мс Посещено Путь +BFS 23.89446 6812 2329 +DFS 84.77876 6796 4537 +A* 28.69542 6791 2329 + +На большом лабиринте DFS показал худшее время и самый длинный путь + +BFS и A* нашли одинаковый путь + +empty.txt +Алгоритм Время мс Посещено Путь +BFS 1.277 + + +04 1176 48 +DFS 7.60228 2304 1176 +A* 0.10094 48 48 + +В лабиринте без стен лучше всего показал себя A* + +Он посетил меньше всего клеток и работал быстрее + +noexit.txt +Алгоритм Время мс Посещено Путь +BFS 0.00370 1 0 +DFS 0.00320 1 0 +A* 0.00412 1 0 + +В этом лабиринте выход недостижим поэтому все алгоритмы быстро закончили поиск + +Графики +------- +Для сравнения времени работы были построены графики для каждого лабиринта + +Графики находятся в папке docs/data + +simple_time.png dead_time.png large_time.png empty_time.png и noexit_time.png + +Вывод +----- +В работе была создана программа для поиска выхода из лабиринта + +Были реализованы BFS DFS и A* а также использованы паттерны Builder Strategy и Observer + +По результатам эксперимента BFS хорошо подходит для поиска кратчайшего пути DFS может найти путь быстрее но он не всегда получается коротким A* хорошо показывает себя на больших и открытых лабиринтах diff --git a/lab2/experiments.py b/lab2/experiments.py new file mode 100644 index 0000000..f669322 --- /dev/null +++ b/lab2/experiments.py @@ -0,0 +1,93 @@ +import csv +import os + +from maze_solver import ( + TextFileMazeBuilder, + MazeSolver, + BFSStrategy, + DFSStrategy, + AStarStrategy +) + +REPEATS = 5 + +MAZES = [ + "simple.txt", + "dead.txt", + "large.txt", + "empty.txt", + "noexit.txt" +] + +STRATEGIES = [ + ("BFS", BFSStrategy()), + ("DFS", DFSStrategy()), + ("A*", AStarStrategy()) +] + +def average(values): + return sum(values) / len(values) + +def run(): + builder = TextFileMazeBuilder() + results = [] + + for maze_name in MAZES: + filename = os.path.join("lab2", "mazes", maze_name) + + print("Maze:", maze_name) + + for strategy_name, strategy in STRATEGIES: + times = [] + visited = [] + path_lengths = [] + + for _ in range(REPEATS): + maze = builder.build_from_file(filename) + + solver = MazeSolver(maze, strategy) + stats = solver.solve() + + times.append(stats.time_ms) + visited.append(stats.visited_count) + path_lengths.append(stats.path_length) + + results.append([ + maze_name, + strategy_name, + average(times), + average(visited), + average(path_lengths) + ]) + + print( + strategy_name, + "time =", average(times), + "visited =", average(visited), + "path =", average(path_lengths) + ) + + os.makedirs("lab2/docs/data", exist_ok=True) + + with open( + "lab2/docs/data/results.csv", + "w", + newline="", + encoding="utf-8" + ) as file: + writer = csv.writer(file) + + writer.writerow([ + "maze", + "strategy", + "time_ms", + "visited_cells", + "path_length" + ]) + + writer.writerows(results) + + print("Results saved to lab2/docs/data/results.csv") + +if __name__ == "__main__": + run() diff --git a/lab2/graphs.py b/lab2/graphs.py new file mode 100644 index 0000000..b49e2eb --- /dev/null +++ b/lab2/graphs.py @@ -0,0 +1,23 @@ +import csv +import matplotlib.pyplot as plt + +with open("lab2/docs/data/results.csv", encoding="utf-8") as file: + rows = list(csv.DictReader(file)) + +mazes = ["simple.txt", "dead.txt", "large.txt", "empty.txt", "noexit.txt"] +strategies = ["BFS", "DFS", "A*"] + +for maze in mazes: + values = [] + + for strategy in strategies: + for row in rows: + if row["maze"] == maze and row["strategy"] == strategy: + values.append(float(row["time_ms"])) + + plt.bar(strategies, values) + plt.title("Время поиска: " + maze) + plt.xlabel("Стратегия") + plt.ylabel("Время, мс") + plt.savefig("lab2/docs/data/" + maze.replace(".txt", "_time.png")) + plt.close() diff --git a/lab2/make_large.py b/lab2/make_large.py new file mode 100644 index 0000000..715daff --- /dev/null +++ b/lab2/make_large.py @@ -0,0 +1,26 @@ +lines = [] + +for y in range(100): + row = [" "] * 100 + + if y == 0 or y == 99: + row = ["#"] * 100 + else: + row[0] = "#" + row[99] = "#" + + lines.append(row) + +lines[1][1] = "S" +lines[98][98] = "E" + +for x in range(4, 96, 4): + gap = 1 if (x // 4) % 2 == 0 else 98 + + for y in range(1, 99): + if y != gap: + lines[y][x] = "#" + +with open("lab2/mazes/large.txt", "w", encoding="utf-8") as file: + for row in lines: + file.write("".join(row) + "\n") diff --git a/lab2/maze_solver.py b/lab2/maze_solver.py new file mode 100644 index 0000000..f99bc2d --- /dev/null +++ b/lab2/maze_solver.py @@ -0,0 +1,284 @@ +from abc import ABC, abstractmethod +from collections import deque +import heapq +import time + +class Cell: + def __init__(self, x, y): + self.x = x + self.y = y + self.is_wall = False + self.is_start = False + self.is_exit = False + + def is_passable(self): + return not self.is_wall + +class Maze: + def __init__(self, width, height): + self.width = width + self.height = height + self.cells = [] + self.start = None + self.exit = None + + for y in range(height): + row = [] + + for x in range(width): + row.append(Cell(x, y)) + + self.cells.append(row) + + def get_cell(self, x, y): + if 0 <= x < self.width and 0 <= y < self.height: + return self.cells[y][x] + + return None + + def get_neighbors(self, cell): + neighbors = [] + + directions = [ + (0, -1), + (0, 1), + (-1, 0), + (1, 0) + ] + + for dx, dy in directions: + neighbor = self.get_cell( + cell.x + dx, + cell.y + dy + ) + + if neighbor and neighbor.is_passable(): + neighbors.append(neighbor) + + return neighbors + +class MazeBuilder(ABC): + @abstractmethod + def build_from_file(self, filename): + pass + +class TextFileMazeBuilder(MazeBuilder): + def build_from_file(self, filename): + with open(filename, "r", encoding="utf-8") as file: + lines = [line.rstrip("\n") for line in file] + + if not lines: + raise ValueError("Файл лабиринта пустой") + + width = len(lines[0]) + + for line in lines: + if len(line) != width: + raise ValueError("Строки лабиринта имеют разную длину") + + maze = Maze(width, len(lines)) + + for y, line in enumerate(lines): + for x, symbol in enumerate(line): + cell = maze.get_cell(x, y) + + if symbol == "#": + cell.is_wall = True + + elif symbol == "S": + if maze.start is not None: + raise ValueError("В лабиринте несколько стартов") + + maze.start = cell + cell.is_start = True + + elif symbol == "E": + if maze.exit is not None: + raise ValueError("В лабиринте несколько выходов") + + maze.exit = cell + cell.is_exit = True + + elif symbol == " ": + pass + + else: + raise ValueError("Неизвестный символ в лабиринте") + + if maze.start is None: + raise ValueError("В лабиринте нет старта") + + if maze.exit is None: + raise ValueError("В лабиринте нет выхода") + + return maze + +class PathFindingStrategy(ABC): + @abstractmethod + def find_path(self, maze, start, exit): + pass + +class BFSStrategy(PathFindingStrategy): + def find_path(self, maze, start, exit): + if start is None or exit is None: + return [], 0 + + queue = deque([(start, [start])]) + visited = {start} + + while queue: + current, path = queue.popleft() + + if current == exit: + return path, len(visited) + + for neighbor in maze.get_neighbors(current): + if neighbor not in visited: + visited.add(neighbor) + queue.append((neighbor, path + [neighbor])) + + return [], len(visited) + +class DFSStrategy(PathFindingStrategy): + def find_path(self, maze, start, exit): + if start is None or exit is None: + return [], 0 + + stack = [(start, [start])] + visited = {start} + + while stack: + current, path = stack.pop() + + if current == exit: + return path, len(visited) + + for neighbor in maze.get_neighbors(current): + if neighbor not in visited: + visited.add(neighbor) + stack.append((neighbor, path + [neighbor])) + + return [], len(visited) + +class AStarStrategy(PathFindingStrategy): + def heuristic(self, a, b): + return abs(a.x - b.x) + abs(a.y - b.y) + + def find_path(self, maze, start, exit): + if start is None or exit is None: + return [], 0 + + heap = [] + counter = 0 + + heapq.heappush( + heap, + (self.heuristic(start, exit), counter, start, [start]) + ) + + g_score = {start: 0} + visited = set() + + while heap: + _, _, current, path = heapq.heappop(heap) + + if current in visited: + continue + + visited.add(current) + + if current == exit: + return path, len(visited) + + for neighbor in maze.get_neighbors(current): + new_cost = g_score[current] + 1 + + if neighbor not in g_score or new_cost < g_score[neighbor]: + g_score[neighbor] = new_cost + counter += 1 + + priority = new_cost + self.heuristic( + neighbor, + exit + ) + + heapq.heappush( + heap, + ( + priority, + counter, + neighbor, + path + [neighbor] + ) + ) + + return [], len(visited) + +class SearchStats: + def __init__(self, path, time_ms, visited_count): + self.path = path + self.time_ms = time_ms + self.visited_count = visited_count + self.path_length = len(path) if path else 0 + +class MazeSolver: + def __init__(self, maze, strategy=None): + self.maze = maze + self.strategy = strategy + self.observers = [] + + def attach(self, observer): + self.observers.append(observer) + + def detach(self, observer): + self.observers.remove(observer) + + def notify(self, event, data=None): + for observer in self.observers: + observer.update(event, data) + + def set_strategy(self, strategy): + self.strategy = strategy + + def solve(self): + if self.strategy is None: + raise ValueError("Стратегия не установлена") + + self.notify("search_started") + + start_time = time.perf_counter() + + path, visited_count = self.strategy.find_path( + self.maze, + self.maze.start, + self.maze.exit + ) + + end_time = time.perf_counter() + + time_ms = (end_time - start_time) * 1000 + + self.notify("search_finished", time_ms) + self.notify("path_found", path) + + return SearchStats( + path, + time_ms, + visited_count + ) + +class Observer(ABC): + @abstractmethod + def update(self, event, data=None): + pass + +class ConsoleView(Observer): + def update(self, event, data=None): + if event == "search_started": + print("Поиск начат") + + elif event == "search_finished": + print(f"Поиск завершен за {data:.3f} мс") + + elif event == "path_found": + print(f"Длина пути: {len(data)}") diff --git a/lab2/mazes/dead.txt b/lab2/mazes/dead.txt new file mode 100644 index 0000000..0ed9b48 --- /dev/null +++ b/lab2/mazes/dead.txt @@ -0,0 +1,20 @@ +#################### +#S # +# # +# # +# # +# # +# ######### # +# # # +# # # +# # # +# # # +# # # +# # # +# # # +# # # +# # +# # +# # +# E# +#################### diff --git a/lab2/mazes/empty.txt b/lab2/mazes/empty.txt new file mode 100644 index 0000000..cf65c33 --- /dev/null +++ b/lab2/mazes/empty.txt @@ -0,0 +1,50 @@ +################################################## +#S # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +# # +#E # +################################################## diff --git a/lab2/mazes/large.txt b/lab2/mazes/large.txt new file mode 100644 index 0000000..79ed92f --- /dev/null +++ b/lab2/mazes/large.txt @@ -0,0 +1,100 @@ +#################################################################################################### +#S # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # E# +#################################################################################################### diff --git a/lab2/mazes/noexit.txt b/lab2/mazes/noexit.txt new file mode 100644 index 0000000..0d9e9c5 --- /dev/null +++ b/lab2/mazes/noexit.txt @@ -0,0 +1,10 @@ +########## +#S######## +########## +########## +########## +########## +########## +########## +########E# +########## diff --git a/lab2/mazes/simple.txt b/lab2/mazes/simple.txt new file mode 100644 index 0000000..b7edabb --- /dev/null +++ b/lab2/mazes/simple.txt @@ -0,0 +1,5 @@ +####### +#S # +# ### # +# E # +####### From f1d9a64911956733a2ab79d87c465e33ef3c0389 Mon Sep 17 00:00:00 2001 From: PaulVA Date: Sat, 5 Sep 2026 19:26:22 +0300 Subject: [PATCH 3/3] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BC=D0=B5=D1=89?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=BB=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=BD=D1=8B=D0=B5=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D1=8B=20=D0=B2=20=D0=BF=D0=B0=D0=BF=D0=BA=D1=83=20PaulVA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {lab1 => PaulVA/lab1}/docs/data/graph_delete.png | Bin {lab1 => PaulVA/lab1}/docs/data/graph_find.png | Bin {lab1 => PaulVA/lab1}/docs/data/graph_insert.png | Bin {lab1 => PaulVA/lab1}/docs/data/results.csv | 0 {lab1 => PaulVA/lab1}/docs/report.md | 0 {lab1 => PaulVA/lab1}/experiments.py | 0 {lab1 => PaulVA/lab1}/graphs.py | 0 {lab1 => PaulVA/lab1}/phonebook.py | 0 {lab2 => PaulVA/lab2}/docs/data/dead_time.png | Bin {lab2 => PaulVA/lab2}/docs/data/empty_time.png | Bin {lab2 => PaulVA/lab2}/docs/data/large_time.png | Bin {lab2 => PaulVA/lab2}/docs/data/noexit_time.png | Bin {lab2 => PaulVA/lab2}/docs/data/results.csv | 0 {lab2 => PaulVA/lab2}/docs/data/simple_time.png | Bin {lab2 => PaulVA/lab2}/docs/report.md | 0 {lab2 => PaulVA/lab2}/experiments.py | 0 {lab2 => PaulVA/lab2}/graphs.py | 0 {lab2 => PaulVA/lab2}/make_large.py | 0 {lab2 => PaulVA/lab2}/maze_solver.py | 0 {lab2 => PaulVA/lab2}/mazes/dead.txt | 0 {lab2 => PaulVA/lab2}/mazes/empty.txt | 0 {lab2 => PaulVA/lab2}/mazes/large.txt | 0 {lab2 => PaulVA/lab2}/mazes/noexit.txt | 0 {lab2 => PaulVA/lab2}/mazes/simple.txt | 0 24 files changed, 0 insertions(+), 0 deletions(-) rename {lab1 => PaulVA/lab1}/docs/data/graph_delete.png (100%) rename {lab1 => PaulVA/lab1}/docs/data/graph_find.png (100%) rename {lab1 => PaulVA/lab1}/docs/data/graph_insert.png (100%) rename {lab1 => PaulVA/lab1}/docs/data/results.csv (100%) rename {lab1 => PaulVA/lab1}/docs/report.md (100%) rename {lab1 => PaulVA/lab1}/experiments.py (100%) rename {lab1 => PaulVA/lab1}/graphs.py (100%) rename {lab1 => PaulVA/lab1}/phonebook.py (100%) rename {lab2 => PaulVA/lab2}/docs/data/dead_time.png (100%) rename {lab2 => PaulVA/lab2}/docs/data/empty_time.png (100%) rename {lab2 => PaulVA/lab2}/docs/data/large_time.png (100%) rename {lab2 => PaulVA/lab2}/docs/data/noexit_time.png (100%) rename {lab2 => PaulVA/lab2}/docs/data/results.csv (100%) rename {lab2 => PaulVA/lab2}/docs/data/simple_time.png (100%) rename {lab2 => PaulVA/lab2}/docs/report.md (100%) rename {lab2 => PaulVA/lab2}/experiments.py (100%) rename {lab2 => PaulVA/lab2}/graphs.py (100%) rename {lab2 => PaulVA/lab2}/make_large.py (100%) rename {lab2 => PaulVA/lab2}/maze_solver.py (100%) rename {lab2 => PaulVA/lab2}/mazes/dead.txt (100%) rename {lab2 => PaulVA/lab2}/mazes/empty.txt (100%) rename {lab2 => PaulVA/lab2}/mazes/large.txt (100%) rename {lab2 => PaulVA/lab2}/mazes/noexit.txt (100%) rename {lab2 => PaulVA/lab2}/mazes/simple.txt (100%) diff --git a/lab1/docs/data/graph_delete.png b/PaulVA/lab1/docs/data/graph_delete.png similarity index 100% rename from lab1/docs/data/graph_delete.png rename to PaulVA/lab1/docs/data/graph_delete.png diff --git a/lab1/docs/data/graph_find.png b/PaulVA/lab1/docs/data/graph_find.png similarity index 100% rename from lab1/docs/data/graph_find.png rename to PaulVA/lab1/docs/data/graph_find.png diff --git a/lab1/docs/data/graph_insert.png b/PaulVA/lab1/docs/data/graph_insert.png similarity index 100% rename from lab1/docs/data/graph_insert.png rename to PaulVA/lab1/docs/data/graph_insert.png diff --git a/lab1/docs/data/results.csv b/PaulVA/lab1/docs/data/results.csv similarity index 100% rename from lab1/docs/data/results.csv rename to PaulVA/lab1/docs/data/results.csv diff --git a/lab1/docs/report.md b/PaulVA/lab1/docs/report.md similarity index 100% rename from lab1/docs/report.md rename to PaulVA/lab1/docs/report.md diff --git a/lab1/experiments.py b/PaulVA/lab1/experiments.py similarity index 100% rename from lab1/experiments.py rename to PaulVA/lab1/experiments.py diff --git a/lab1/graphs.py b/PaulVA/lab1/graphs.py similarity index 100% rename from lab1/graphs.py rename to PaulVA/lab1/graphs.py diff --git a/lab1/phonebook.py b/PaulVA/lab1/phonebook.py similarity index 100% rename from lab1/phonebook.py rename to PaulVA/lab1/phonebook.py diff --git a/lab2/docs/data/dead_time.png b/PaulVA/lab2/docs/data/dead_time.png similarity index 100% rename from lab2/docs/data/dead_time.png rename to PaulVA/lab2/docs/data/dead_time.png diff --git a/lab2/docs/data/empty_time.png b/PaulVA/lab2/docs/data/empty_time.png similarity index 100% rename from lab2/docs/data/empty_time.png rename to PaulVA/lab2/docs/data/empty_time.png diff --git a/lab2/docs/data/large_time.png b/PaulVA/lab2/docs/data/large_time.png similarity index 100% rename from lab2/docs/data/large_time.png rename to PaulVA/lab2/docs/data/large_time.png diff --git a/lab2/docs/data/noexit_time.png b/PaulVA/lab2/docs/data/noexit_time.png similarity index 100% rename from lab2/docs/data/noexit_time.png rename to PaulVA/lab2/docs/data/noexit_time.png diff --git a/lab2/docs/data/results.csv b/PaulVA/lab2/docs/data/results.csv similarity index 100% rename from lab2/docs/data/results.csv rename to PaulVA/lab2/docs/data/results.csv diff --git a/lab2/docs/data/simple_time.png b/PaulVA/lab2/docs/data/simple_time.png similarity index 100% rename from lab2/docs/data/simple_time.png rename to PaulVA/lab2/docs/data/simple_time.png diff --git a/lab2/docs/report.md b/PaulVA/lab2/docs/report.md similarity index 100% rename from lab2/docs/report.md rename to PaulVA/lab2/docs/report.md diff --git a/lab2/experiments.py b/PaulVA/lab2/experiments.py similarity index 100% rename from lab2/experiments.py rename to PaulVA/lab2/experiments.py diff --git a/lab2/graphs.py b/PaulVA/lab2/graphs.py similarity index 100% rename from lab2/graphs.py rename to PaulVA/lab2/graphs.py diff --git a/lab2/make_large.py b/PaulVA/lab2/make_large.py similarity index 100% rename from lab2/make_large.py rename to PaulVA/lab2/make_large.py diff --git a/lab2/maze_solver.py b/PaulVA/lab2/maze_solver.py similarity index 100% rename from lab2/maze_solver.py rename to PaulVA/lab2/maze_solver.py diff --git a/lab2/mazes/dead.txt b/PaulVA/lab2/mazes/dead.txt similarity index 100% rename from lab2/mazes/dead.txt rename to PaulVA/lab2/mazes/dead.txt diff --git a/lab2/mazes/empty.txt b/PaulVA/lab2/mazes/empty.txt similarity index 100% rename from lab2/mazes/empty.txt rename to PaulVA/lab2/mazes/empty.txt diff --git a/lab2/mazes/large.txt b/PaulVA/lab2/mazes/large.txt similarity index 100% rename from lab2/mazes/large.txt rename to PaulVA/lab2/mazes/large.txt diff --git a/lab2/mazes/noexit.txt b/PaulVA/lab2/mazes/noexit.txt similarity index 100% rename from lab2/mazes/noexit.txt rename to PaulVA/lab2/mazes/noexit.txt diff --git a/lab2/mazes/simple.txt b/PaulVA/lab2/mazes/simple.txt similarity index 100% rename from lab2/mazes/simple.txt rename to PaulVA/lab2/mazes/simple.txt