diff --git a/nikolaevda/task2/Zadanie2.py b/nikolaevda/task2/Zadanie2.py index b595b84..4b218df 100644 --- a/nikolaevda/task2/Zadanie2.py +++ b/nikolaevda/task2/Zadanie2.py @@ -664,9 +664,6 @@ class GameController: 'player': self.player }) - - - class MazeGenerator: """генератор тестовых лабиринтов различной сложности""" @@ -747,13 +744,26 @@ class MazeGenerator: for y in range(height): for x in range(width): cell = maze.get_cell(x, y) - if not cell.is_wall: + if cell and not cell.is_wall: dist = abs(x - start_x) + abs(y - start_y) if dist > max_dist: max_dist = dist farthest = (x, y) + + # Устанавливаем выход maze.set_exit(farthest[0], farthest[1]) + # Дополнительная проверка: если выход всё ещё None - создаём принудительно + if maze.exit is None: + for y in range(height): + for x in range(width): + cell = maze.get_cell(x, y) + if cell and not cell.is_wall and not cell.is_start: + maze.set_exit(x, y) + break + if maze.exit: + break + return maze @staticmethod @@ -784,7 +794,6 @@ class MazeGenerator: line += '.' f.write(line + '\n') - class ExperimentRunner: """запуск экспериментов и сбор статистики""" @@ -858,7 +867,12 @@ class ExperimentRunner: print(f"\n Лабиринт: {maze_name}") print(f" Размер: {maze.width}x{maze.height}") print(f" Старт: ({maze.start.x}, {maze.start.y})") - print(f" Выход: ({maze.exit.x}, {maze.exit.y})") + + # Проверяем, есть ли выход + if maze.exit: + print(f" Выход: ({maze.exit.x}, {maze.exit.y})") + else: + print(f" Выход: ОТСУТСТВУЕТ") for strategy in strategies: print(f" → {strategy.get_name()}...", end=" ", flush=True) @@ -869,11 +883,15 @@ class ExperimentRunner: print(f"{status} {result['avg_time_ms']:.2f}мс, " f"{result['avg_visited_cells']:.0f} клеток, " f"{result['avg_path_length']:.1f} шагов") - + def save_to_csv(self, filename="experiment_results.csv"): import csv + + if not self.results: + print("Нет результатов для сохранения") + return - with open(filename, 'w', newline='', encoding='utf-8') as csvfile: + with open(filename, 'w', newline='', encoding='utf-8-sig') as csvfile: fieldnames = [ 'maze_name', 'strategy', 'runs', 'avg_time_ms', 'min_time_ms', 'max_time_ms', @@ -881,13 +899,19 @@ class ExperimentRunner: 'avg_path_length', 'min_path_length', 'max_path_length', 'path_found' ] - writer = csv.DictWriter(csvfile, fieldnames=fieldnames) + writer = csv.DictWriter(csvfile, fieldnames=fieldnames, delimiter=';') writer.writeheader() for result in self.results: writer.writerow(result) + + if os.path.exists(filename): + print(f"\n Результаты сохранены в {filename}") + print(f" Размер файла: {os.path.getsize(filename)} байт") + else: + print(f"\n Ошибка: файл {filename} не создан") + - print(f"\n Результаты сохранены в {filename}") def print_summary(self): print("СВОДНАЯ СТАТИСТИКА ЭКСПЕРИМЕНТОВ") @@ -990,8 +1014,17 @@ def plot_experiment_results(csv_filename="experiment_results.csv"): print("Файл результатов не найден") return - df = pd.read_csv(csv_filename) + if os.path.getsize(csv_filename) == 0: + print(f"Файл {csv_filename} пустой. Сначала запустите эксперименты.") + return + df = pd.read_csv(csv_filename, sep=';', encoding='utf-8-sig') + + if 'strategy' not in df.columns: + print(f"Ошибка: в файле {csv_filename} нет колонки 'strategy'") + print(f"Доступные колонки: {list(df.columns)}") + return + fig = plt.figure(figsize=(16, 12)) fig.suptitle('Сравнение алгоритмов поиска в лабиринте', fontsize=16) @@ -1072,7 +1105,27 @@ def plot_by_maze(csv_filename="experiment_results.csv"): if not os.path.exists(csv_filename): return - df = pd.read_csv(csv_filename) + df = pd.read_csv(csv_filename, sep=';', encoding='utf-8-sig') + + if 'maze_name' not in df.columns: + for col in df.columns: + if 'maze' in col.lower() or 'name' in col.lower(): + df.rename(columns={col: 'maze_name'}, inplace=True) + break + + if 'maze_name' not in df.columns: + print("Ошибка: колонка 'maze_name' не найдена") + return + + mazes = df['maze_name'].unique() + + print("Колонки в файле:", list(df.columns)) + + if 'maze_name' not in df.columns: + print("Колонка 'maze_name' не найдена. Доступны:", list(df.columns)) + return + + mazes = df['maze_name'].unique() mazes = df['maze_name'].unique() fig, axes = plt.subplots(len(mazes), 3, figsize=(15, 4 * len(mazes))) @@ -1116,7 +1169,35 @@ def print_analysis(csv_filename="experiment_results.csv"): if not os.path.exists(csv_filename): return - df = pd.read_csv(csv_filename) + df = pd.read_csv(csv_filename, sep=';', encoding='utf-8-sig') + + # ПРОВЕРКА: какие колонки есть в файле + print("DEBUG: Колонки в файле:", list(df.columns)) + + # Если колонка называется не 'strategy' - переименовываем + if 'strategy' not in df.columns: + # Ищем похожую колонку + for col in df.columns: + if 'strategy' in col.lower() or 'algo' in col.lower(): + df.rename(columns={col: 'strategy'}, inplace=True) + break + + if 'strategy' not in df.columns: + print("Ошибка: колонка 'strategy' не найдена в CSV") + return + + print("АНАЛИЗ ЭФФЕКТИВНОСТИ АЛГОРИТМОВ") + + print("\nОбщая статистика по алгоритмам:") + print(f"{'Алгоритм':<25} {'Время(мс)':<12} {'Посещено':<12} {'Длина пути':<12} {'Найден %':<10}") + + for strategy in df['strategy'].unique(): + data = df[df['strategy'] == strategy] + avg_time = data['avg_time_ms'].mean() + avg_visited = data['avg_visited_cells'].mean() + avg_length = data['avg_path_length'].mean() + found_rate = data['path_found'].mean() * 100 + print(f"{strategy:<25} {avg_time:<12.2f} {avg_visited:<12.0f} {avg_length:<12.1f} {found_rate:<10.1f}%") print("АНАЛИЗ ЭФФЕКТИВНОСТИ АЛГОРИТМОВ") @@ -1217,6 +1298,7 @@ def run_full_analysis(): print_analysis() + def run_experiments(): """Запуск экспериментов с построением графиков и анализом""" runner = ExperimentRunner(runs_per_experiment=5) @@ -1228,6 +1310,7 @@ def run_experiments(): run_full_analysis() + if __name__ == "__main__": if len(sys.argv) > 1 and sys.argv[1] == 'experiment': run_experiments() diff --git a/nikolaevda/task2/algorithm_comparison.png b/nikolaevda/task2/algorithm_comparison.png new file mode 100644 index 0000000..0c7e332 Binary files /dev/null and b/nikolaevda/task2/algorithm_comparison.png differ diff --git a/nikolaevda/task2/experiment_results.csv b/nikolaevda/task2/experiment_results.csv new file mode 100644 index 0000000..07f530e --- /dev/null +++ b/nikolaevda/task2/experiment_results.csv @@ -0,0 +1,29 @@ +maze_name;strategy;runs;avg_time_ms;min_time_ms;max_time_ms;avg_visited_cells;min_visited_cells;max_visited_cells;avg_path_length;min_path_length;max_path_length;path_found +tiny_simple (10x10);BFS (Поиск в ширину);5;0.10344001930207014;0.0868999632075429;0.15590002294629812;28.0;28;28;19.0;19;19;True +tiny_simple (10x10);DFS (Поиск в глубину);5;0.07182001136243343;0.05929998587816954;0.08929998148232698;28.0;28;28;19.0;19;19;True +tiny_simple (10x10);A Star;5;0.18986002542078495;0.1583000412210822;0.2394000766798854;28.0;28;28;19.0;19;19;True +tiny_simple (10x10);Дейкстра (Dijkstra);5;0.2083600265905261;0.1431000418961048;0.3237000200897455;28.0;28;28;19.0;19;19;True +small_empty (20x20);BFS (Поиск в ширину);5;1.2823000084608793;1.1743999784812331;1.4915000647306442;400.0;400;400;39.0;39;39;True +small_empty (20x20);DFS (Поиск в глубину);5;0.9971400257200003;0.9467999916523695;1.153100049123168;400.0;400;400;191.0;191;191;True +small_empty (20x20);A Star;5;2.6846999768167734;2.398099983111024;2.9609999619424343;400.0;400;400;39.0;39;39;True +small_empty (20x20);Дейкстра (Dijkstra);5;2.510580001398921;2.1893999073654413;2.994599984958768;400.0;400;400;39.0;39;39;True +medium_dfs (30x30);BFS (Поиск в ширину);5;0.6412999937310815;0.5982000147923827;0.7941999938338995;171.0;171;171;105.0;105;105;True +medium_dfs (30x30);DFS (Поиск в глубину);5;0.35470002330839634;0.34390005748718977;0.37720007821917534;110.0;110;110;105.0;105;105;True +medium_dfs (30x30);A Star;5;0.8171399822458625;0.7591999601572752;0.8969999616965652;141.0;141;141;105.0;105;105;True +medium_dfs (30x30);Дейкстра (Dijkstra);5;0.9974599815905094;0.8565000025555491;1.2263000244274735;171.0;171;171;105.0;105;105;True +medium_complex (40x40);BFS (Поиск в ширину);5;2.802439988590777;2.5909000542014837;3.390899975784123;614.0;614;614;373.0;373;373;True +medium_complex (40x40);DFS (Поиск в глубину);5;1.8086799886077642;1.4740999322384596;2.945499960333109;397.0;397;397;373.0;373;373;True +medium_complex (40x40);A Star;5;3.598040039651096;3.0396999791264534;4.724400001578033;569.0;569;569;373.0;373;373;True +medium_complex (40x40);Дейкстра (Dijkstra);5;3.372700000181794;2.929799957200885;4.301499924622476;614.0;614;614;373.0;373;373;True +large_dfs (50x50);BFS (Поиск в ширину);5;2.029319992288947;1.6838000155985355;3.06529994122684;412.0;412;412;305.0;305;305;True +large_dfs (50x50);DFS (Поиск в глубину);5;1.2084600050002337;1.1607999913394451;1.3439999893307686;314.0;314;314;305.0;305;305;True +large_dfs (50x50);A Star;5;2.5132999988272786;2.017199993133545;3.4434000262990594;366.0;366;366;305.0;305;305;True +large_dfs (50x50);Дейкстра (Dijkstra);5;2.3565199924632907;1.976999919861555;3.297399962320924;412.0;412;412;305.0;305;305;True +very_large_dfs (100x100);BFS (Поиск в ширину);5;28.673699987120926;26.941100019030273;32.57150005083531;3566.0;3566;3566;1813.0;1813;1813;True +very_large_dfs (100x100);DFS (Поиск в глубину);5;15.021399967372417;14.021800016053021;16.41029992606491;1995.0;1995;1995;1813.0;1813;1813;True +very_large_dfs (100x100);A Star;5;20.14593998901546;19.036200013943017;22.409999975934625;3381.0;3381;3381;1813.0;1813;1813;True +very_large_dfs (100x100);Дейкстра (Dijkstra);5;18.126800004392862;16.766700078733265;19.753700005821884;3566.0;3566;3566;1813.0;1813;1813;True +no_exit (20x20);BFS (Поиск в ширину);5;0.003600004129111767;0.001300009898841381;0.011499971151351929;0.0;0;0;0.0;0;0;False +no_exit (20x20);DFS (Поиск в глубину);5;0.0007200054824352264;0.000300002284348011;0.001900014467537403;0.0;0;0;0.0;0;0;False +no_exit (20x20);A Star;5;0.0005800044164061546;0.000300002284348011;0.001300009898841381;0.0;0;0;0.0;0;0;False +no_exit (20x20);Дейкстра (Dijkstra);5;0.0006799818947911263;0.000300002284348011;0.0014998950064182281;0.0;0;0;0.0;0;0;False diff --git a/nikolaevda/task2/maze_detailed_analysis.png b/nikolaevda/task2/maze_detailed_analysis.png new file mode 100644 index 0000000..b1fe176 Binary files /dev/null and b/nikolaevda/task2/maze_detailed_analysis.png differ diff --git a/nikolaevda/task2/test_large_dfs_50x50.txt b/nikolaevda/task2/test_large_dfs_50x50.txt new file mode 100644 index 0000000..acb36c4 --- /dev/null +++ b/nikolaevda/task2/test_large_dfs_50x50.txt @@ -0,0 +1,50 @@ +################################################## +#S......#.....#...........#.........#...#.......## +#######.#####.#.#.#######.#.#######.#.###.#.###.## +#...#...#...#...#.....#.....#.....#.#.#...#.#...## +###.#.###.#.#.#######.#########.#.#.#.#.###.#.#### +#...#.#...#.#.......#.#.......#.#.#.#.#...#.#...## +#.#.#.#.###.#######.#.#.#####.#.#.#.#.###.#.###.## +#.#.#.#.#.#.......#.#...#...#.#.#.#.#...#.#.#...## +#.###.#.#.#######.#######.#.#.#.#.#.#.#.#.#.###### +#.#...#.#.......#...#...#.#...#.#.#.#.#...#.....## +#.#.###.#.#####.###.#.#.#.#######.#.###########.## +#.#.....#.#...#.#.#.#.#.#.......#.#.........#...## +#.#######.#.#.#.#.#.#.#.#######.#.#########.#.#.## +#.....#.....#.#.#.#.#.#.#.......#.........#.#.#.## +#.###.#####.#.#.#.#.#.#.#.#######.#######.#.#.#### +#...#.....#.#.#...#...#...#.....#.#.......#.#...## +#.#.#####.###.###.#########.###.#.#.#######.#.#.## +#.#.#...#.....#.#.#.....#...#...#.#...#.....#.#.## +#.#.#.#########.#.#.###.#.###.#.#.###.#.#######.## +#.#.#...........#...#...#.#...#.#.#...#.#.....#.## +#.#.###.#######.#####.###.#.#####.#.###.###.#.#.## +#.#...#.......#...#.#...#.#.#.....#.....#...#.#.## +#.###.#######.###.#.###.#.#.#.###########.###.#.## +#...#...#...#.#.......#.#.#.#.....#.......#.#...## +###.###.#.#.#.#######.#.###.#####.#.#######.###.## +#...#...#.#...#...#...#.........#.#...#.....#...## +#.###.###.#####.#.###.#.#######.#.#.#.#####.#.#### +#.#.#...#.#...#.#...#.#.#.....#.#.#.#...#...#.#.## +#.#.###.#.#.#.#.###.###.#.###.#.#.#####.#.#.#.#.## +#...#...#.#.#...#.#.....#...#.#.#.......#.#.#.#.## +#####.###.#.#####.#########.#.#.#########.#.#.#.## +#.....#.#...#.......#.....#.#.#.......#...#.#.#.## +#.#####.#.#########.#.#.#.#.#.#########.#.###.#.## +#.#...#.....#.......#.#.#.#.#.#.........#...#.#.## +#.#.#.#####.#.#######.#.###.#.#.#########.#.#.#.## +#...#.#...#...#.......#.....#...#...#...#.#.#...## +#.###.#.#.###.#.#############.###.###.#.#.#.###.## +#.#.#...#...#.#.#.....#.#...#.#...#...#.#.#.#...## +#.#.#######.#.#.###.#.#.#.#.#.###.#.###.###.#.#### +#...#.....#.#.#...#.#...#.#.#.....#.#.#.#...#...## +###.#.#.###.#####.#.###.#.#.#######.#.#.#.#.###.## +#...#.#...#.....#.#.#...#.#.........#.....#.#.#.## +#.#######.###.###.#.#####.#####.###########.#.#.## +#.#.........#.#...#...#...#.....#.........#...#.## +#.#.#####.###.#.###.#.#.#########.#######.#.###.## +#...#.....#...#.#...#.#...#...#...#.....#.#.#...## +#####.#####.###.#####.###.#.#.#.#####.#.#.###.#### +#.........#.............#...#.........#.#......E## +################################################## +################################################## diff --git a/nikolaevda/task2/test_medium_complex_40x40.txt b/nikolaevda/task2/test_medium_complex_40x40.txt new file mode 100644 index 0000000..88715bb --- /dev/null +++ b/nikolaevda/task2/test_medium_complex_40x40.txt @@ -0,0 +1,40 @@ +######################################## +#S..........#.............#.......#...## +###########.#.#####.#####.#.#####.#.#### +#.......#...#.....#.....#.#.#.#...#...## +#.#####.#.#######.#####.#.#.#.#.###.#.## +#.#...#.#.#.#.......#...#.#.#.....#.#.## +#.#.#.#.#.#.#.#######.###.#.#####.###.## +#.#.#.#.#.#...#.......#...#.....#.....## +#.#.#.#.#.#####.#######.#######.#####.## +#.#.#.#.#.....#.#.....#.........#.#...## +#.#.#.#######.#.#####.###########.#.#### +#...#.......#...#.....#...........#...## +#######.###.#####.#####.#########.###.## +#.......#.......#.....#...#.....#...#.## +#.#############.#####.###.#.#######.#.## +#.#...........#...#...#...#...#.....#.## +#.#.#########.###.#.#.#.###.#.#.#.###.## +#.#.....#...#.#.....#.#...#.#.#.#.#...## +#.#####.###.#.###########.###.#.###.#### +#.......#...#.#.........#.....#...#...## +#.#######.###.#.#####.###.#######.###.## +#...#.......#.#...#.#.#...#.......#...## +###.#######.#.###.#.#.#.###.#######.#### +#.#.......#.#.....#.#...#.#.......#.#.## +#.#######.#.#######.#####.#######.#.#.## +#.......#...#.....#.........#...#.#.#.## +#.#####.###.###.#.###.#####.#.###.#.#.## +#.#...#...#.....#.#...#...#...#...#.#.## +#.###.#.#########.#.###.#####.#.###.#.## +#.#...#.........#...#.........#...#.#.## +#.#.###########.#####.###########.#.#.## +#.#...........#.....#.#...#.....#...#.## +#.#######.#.###.#####.#.#.#####.#####.## +#.#.......#.#...#...#...#.#.....#.....## +#.#.#######.#.###.#.#####.#.###.###.#.## +#...#.....#.#.....#...#...#...#...#.#.## +#####.###.#.#######.###.#####.###.###.## +#.......#.........#...........#......E## +######################################## +######################################## diff --git a/nikolaevda/task2/test_medium_dfs_30x30.txt b/nikolaevda/task2/test_medium_dfs_30x30.txt new file mode 100644 index 0000000..4749e5d --- /dev/null +++ b/nikolaevda/task2/test_medium_dfs_30x30.txt @@ -0,0 +1,30 @@ +############################## +#S....#.........#...........## +#####.#.#.#####.#.#########.## +#...#.#.#.#.....#.....#...#.## +#.###.###.#.#########.#.#.#.## +#.#...#...#.#.......#.#.#.#.## +#.#.###.#####.#####.#.#.#.#.## +#.#.#...#...#.#...#.#.#.#.#.## +#.#.###.#.#.#.#.###.#.#.###.## +#.#...#...#.#.#.#...#.#...#.## +#.###.#.###.#.#.#.#.#.###.#.## +#...#.#.#.#.#.#.#.#.#.....#.## +#.###.#.#.#.#.#.#.#.#####.#.## +#.....#...#.....#.#.#.....#.## +#.#####.#######.#.###.#####.## +#.#...#.#...#...#...#.#.#...## +#.#.#.###.#.#.#####.#.#.#.#.## +#...#...#.#.#...#.#.#.#.#.#.## +#######.#.#.###.#.#.#.#.#.#.## +#.....#...#...#...#.....#.#.## +#.###.#######.###########.#.## +#.#.......#...#.......#...#.## +###.#.#####.###.#####.#.###### +#...#.#...#.#.......#.#.....## +#.#####.#.#.#######.#.###.#.## +#.....#.#.#.#.....#.#...#.#.## +#.###.#.#.#.#.###.#.###.###.## +#...#...#.....#.....#......E## +############################## +############################## diff --git a/nikolaevda/task2/test_no_exit_20x20.txt b/nikolaevda/task2/test_no_exit_20x20.txt new file mode 100644 index 0000000..de83995 --- /dev/null +++ b/nikolaevda/task2/test_no_exit_20x20.txt @@ -0,0 +1,20 @@ +#################### +#S..#.............## +###.#.###########.## +#.#.#.#.........#.## +#.#.#.###.###.###.## +#.#.#...#...#.#...## +#.#.###.###.#.#.#.## +#.#.#.....#.#.#.#.## +#.#.#####.###.#.#### +#.#.....#.#...#...## +#.#####.#.#.#####.## +#.#...#.#.#...#...## +#.#.#.#.#.###.#.#### +#...#...#...#.#...## +#.#########.#.###.## +#.....#...#...#...## +#####.#.#.#####.#.## +#.......#.......#### +#################### +#################### diff --git a/nikolaevda/task2/test_small_empty_20x20.txt b/nikolaevda/task2/test_small_empty_20x20.txt new file mode 100644 index 0000000..b7bd7ab --- /dev/null +++ b/nikolaevda/task2/test_small_empty_20x20.txt @@ -0,0 +1,20 @@ +S................... +.................... +.................... +.................... +.................... +.................... +.................... +.................... +.................... +.................... +.................... +.................... +.................... +.................... +.................... +.................... +.................... +.................... +.................... +...................E diff --git a/nikolaevda/task2/test_tiny_simple_10x10.txt b/nikolaevda/task2/test_tiny_simple_10x10.txt new file mode 100644 index 0000000..f05e625 --- /dev/null +++ b/nikolaevda/task2/test_tiny_simple_10x10.txt @@ -0,0 +1,10 @@ +S.######## +...####### +#...###### +##...##### +###...#### +####...### +#####...## +######...# +#######... +########.E diff --git a/nikolaevda/task2/test_very_large_dfs_100x100.txt b/nikolaevda/task2/test_very_large_dfs_100x100.txt new file mode 100644 index 0000000..0f90b30 --- /dev/null +++ b/nikolaevda/task2/test_very_large_dfs_100x100.txt @@ -0,0 +1,100 @@ +#################################################################################################### +#S#...............#.....#.....#.....#.......#...#.........#...#...#.......................#.....#.## +#.#######.#########.#.#.###.#.#.###.#.#.###.###.#.#.#####.#.###.#.#.#########.#####.#####.###.#.#.## +#.......#.#.........#.#.....#.#...#.#.#.#.#...#...#.#.....#.....#...#.......#.#.....#...#...#.#.#.## +#######.#.#.#########.#######.###.#.###.#.###.#####.#####.#.#######.#.###.###.#######.#.###.#.#.#.## +#...#...#...#...#.....#.....#...#.#.....#...#.....#.....#.#...#...#...#...#...#.......#.#.#...#...## +#.#.#.#####.#.#.#.#####.###.###.#.#########.#####.#####.#.#####.#.#####.###.###.#######.#.#######.## +#.#.#.....#.#.#.#.......#.#.#.#...#...#.........#.......#.......#...#.#.#...#...#...#.#.#.........## +#.#.#####.###.#.#####.###.#.#.#####.#.#.#.#########################.#.#.#.###.###.#.#.#.#######.#### +#.#.....#.#...#.....#.....#.#.......#.#.#.#...#...........#.....#...#...#.........#...#.......#...## +#.#####.#.#.#######.#####.#.###.#####.###.#.#.#.###.#####.#.#.###.###.#################.#####.###.## +#.#...#...#.#.#.....#.....#...#.#...#.....#.#...#...#...#...#.#...#.#...#.#...#...#...#.....#.#...## +#.###.#####.#.#.#######.#####.#.###.#####.#.#####.#####.#####.#.###.###.#.#.#.#.#.#.#.###.###.###### +#.......#...#.#.......#.....#.#...#.......#.....#.#...#.......#.#.....#...#.#.#.#.#.#.#...#...#...## +#######.#.#.#.#######.#######.###.#.###########.#.#.#.#.#######.#.###.###.#.#.#.#.#.#.#####.###.#.## +#.....#.#.#.#.................#...#.#.........#.#...#.#.....#.#.#...#.#...#.#.#.#...#...#...#...#.## +#####.#.#.#.###################.###.#.###.#####.#####.#####.#.#.#####.#.###.#.#.#######.#.#.#.###.## +#.....#.#.#...........#...#.....#.#...#...#...#.....#.#...#...#.....#...#...#.#.#.#.....#.#.#.#...## +#.#####.#########.###.#.#.#.#####.###.#####.#.#####.#.#.#.###.#####.#.###.###.#.#.#.#####.###.#.#### +#.#...#.#...#...#.#...#.#.#.....#...#.#.....#.......#.#.#.#.#.#...#.#...#.#.#...#.#...#.......#...## +#.#.#.#.#.#.#.#.#.#.###.#.#.###.#.###.#.#############.#.#.#.#.#.###.###.#.#.#####.###.#.#########.## +#.#.#.#...#...#.#.#.....#.#.#...#...#.#...#.....#.....#.#.#.....#...#...#.#.......#...#.#.....#...## +#.#.#.#########.#########.#.#.#####.#.###.#####.#.###.#.#.#######.#######.#.###.#.#.###.#.###.#.#### +#...#.........#.#.......#.#.#.....#.#.#.#.....#.#...#.#.#.......#.......#.#.#...#.#.#...#.#...#...## +#.#######.#####.#.#####.#.#######.#.#.#.#####.#.###.#.#.#######.#######.#.###.###.#.#####.#.###.#.## +#.....#.#.#...#...#...#...#...#...#...#.....#...#.#.#.#.#.....#...#...#...#...#...#.#.....#.#.#.#.## +#####.#.#.#.#.#####.#######.#.#.###.###.###.###.#.#.###.#####.#.#.###.#####.#######.#.#####.#.#.#.## +#...#.#.#...#.....#.........#...#.#.....#...#...#.#.....#...#.#.#.#...#.#...#.....#...#.#...#...#.## +#.#.#.#.#####.###.#######.#######.#.#####.###.###.#######.#.#.#.#.#.#.#.#.#.#.###.#####.#.#######.## +#.#.#...#...#.#.......#...#.....#...#...#...#...#.........#...#.#...#.#.#.#.....#.......#...#.....## +#.#####.#.#.#.#######.#.###.#.#.#.###.#.#######.#.###########.#.#####.#.#.#######.#####.###.#.###.## +#.......#.#.#...#...#...#...#.#.#...#.#.......#.#...#.......#.#...#...#.....#...#.#...#.#...#.#...## +#.#########.###.#.###########.###.###.#######.#.###.#####.#.#.###.#.#########.#.#.#.#.###.###.#.#### +#...#.........#.#.............#...#...#.......#...#.#...#.#.#.#.#.#...........#.#...#.#...#...#...## +###.#.#.###.###.#.#.###########.###.###.#########.#.#.#.#.###.#.#.#############.#.###.#.#####.###.## +#...#.#.#...#...#.#...#.....#...#...#.#.#.........#...#.#...#...#.#.......#.....#...#.#.#.....#.#.## +#.#####.#.###.#######.#.###.#.###.###.#.#.#############.###.###.#.#.#####.#.#####.###.#.###.###.#.## +#.#.....#...#.....#...#.#.#.#...#.....#...#.............#.....#.#...#...#.#.....#.#...#.....#...#.## +#.#.#.#####.#####.#.###.#.#.###.#####.#####.###.#########.#####.#####.#.#.#####.###.###########.#.## +#.#.#.#...#...#...#...#...#...#.#...#.#.....#...#.....#.....#...#.....#.#.#...#...#.#...#.......#.## +#.###.#.#.#.###.###.#.###.###.#.###.#.#######.###.#.#.#####.#.###.#####.#.#.#####.#.#.#.#.#.#####.## +#.....#.#.#.#...#...#.....#...#.....#.........#...#.#...#...#.#.#.#...#...#.........#.#...#.......## +#######.#.#.#.#############.#.#####.###############.###.#.#.#.#.#.#.#.#############.#.############## +#.......#.#.#.#...#.........#.#...#.......#.....#...#.#.#.#.#.#.#.#.#.......#...#...#...#.......#.## +###.#######.#.#.#.#.#########.###.#######.#.#.#.#.###.#.#.#.#.#.#.#.#######.#.#.###.###.#.#####.#.## +#...#.....#.#...#.#...#...#.#...#...#.....#.#.#...#.....#.#.#...#...#.....#...#...#.#...#...#...#.## +#.###.###.#.#####.###.#.#.#.###.###.#.#######.#####.#####.#####.#####.###########.#.#.#####.###.#.## +#.....#.#...#...#...#...#.#...#.#...#...#...#.#...#.#.....#...#.#.....#...........#.#.....#...#...## +#.#####.#####.#.###.#####.#.#.#.#.#.###.#.#.#.#.###.###.#.#.#.#.#.###.#.#########.#######.#.#.###### +#.#...#.......#...#.#...#.#.#.....#.#...#.#...#.........#.#.#...#.#...#...#.......#.....#.#.#.....## +#.#.#.###.#######.#.#.#.#.#########.#.###.###.#######.#####.#####.#.#####.#.#####.#.###.#.#.#####.## +#...#.....#.#.....#.#.#.#.#.....#...#.....#...#.....#.#.....#.....#.#...#.#.#...#.#.#.#.#.#...#...## +###########.#.#####.#.#.#.#.###.#######.#####.#.###.###.#####.#.###.###.#.#.#.#.#.#.#.#.#.#.###.#.## +#.#...#.....#.#.#...#.#.#.#...#.........#...#.#.#.#...#.#.....#.#...#...#.#.#.#.#.#.#.#...#.#...#.## +#.#.#.#.#.###.#.#.#.#.#.#.###.###########.#.#.#.#.###.#.###.###.#.###.#.#.###.#.#.#.#.#######.###.## +#.#.#...#.....#.#.#.#.#.#.........#.......#.#.#.#...#.#...#.#...#.....#.#.....#.#.#.#.........#...## +#.#.###########.#.###.#.###########.#######.#.#.#.###.###.###.#########.#######.###.#.#####.#####.## +#.#.....#...#...#.....#.........#...#...#...#.#.#.#.....#...#.#.....#.....#...#.....#...#.#.#...#.## +#.#####.#.#.###.###############.#.###.#.#.#####.#.#.#.#####.#.#.###.#.#####.#.#######.#.#.#.#.#.#### +#.....#.#.#.....#.....#.......#.#.....#.#.......#.#.#.#...#.#...#...#...#...#.....#...#.#...#.#...## +#.#####.#.#####.#.#.#.#.#.#####.#######.#########.#.###.#.#.#.###.#####.#.#####.#.#.###.#####.###.## +#.#.....#.#.#...#.#.#...#.#...........#.#.....#...#.#...#...#.#.#.#.....#.#...#.#.#.#.#.....#...#.## +#.#.#####.#.#.#####.#####.#.#######.###.#.#.#.#.#.#.#.#######.#.#.#######.###.#.#.#.#.#####.###.#.## +#.#.#.....#...#.....#.#...#.....#...#...#.#.#.#.#.#...#.....#...#.............#.#.#...#...#.....#.## +#.#.#.#####.#####.###.#.#######.#.###.###.#.#.###.#####.###.#.#####.###########.#.###.###.#######.## +#.#...#...#.#.....#.#...#.....#.#...#.#.#.#.#...........#.#.#.#...#.#...........#.#.#...#.......#.## +#.#######.#.#.#####.#.###.###.#.#.###.#.#.#.#############.#.###.#.#.#.###########.#.###.#.#.#####.## +#.........#...#.....#.#...#.....#.#...#.#.#.#.......#.....#.#...#.#.#.......#...#.....#.#.#.#...#.## +#.#############.#.###.#.###########.###.#.#.#.#####.#.#.###.#.###.#.#####.#.###.#.#####.###.#.#.#.## +#...............#.#...#.............#.....#...#...#.#.#.#...#.#...#.#...#.#...#...#.....#...#.#.#.## +#.#####.#####.#####.###################.#####.#.#.#.###.#.###.#.#####.#.#.###.#####.#####.###.#.#.## +#.#...#.#.....#...#...#...............#.#...#...#.#...#...#...#.......#.#...#.#.....#.....#...#.#.## +###.#.###.###.#.#.###.#.#########.###.#.#.#.###.#####.###.#.###########.#####.#.#####.#####.###.#.## +#...#.#...#.#.#.#.....#.....#.....#.#.#.#.#...#.#...#...#...#.........#.......#.......#.....#...#.## +#.###.#.###.#.#.#############.#####.#.###.###.###.#.#.#.###.#.#######.#######.#######.#.#######.#.## +#.#...#.#...#.#.....#.......#...#...#.....#.#.....#.#.#...#.#.#.....#.#.......#.......#...#...#...## +#.#.###.#.#.#.#####.#.#####.###.#.#.#######.#######.#.###.#.#.#.#.#.#.#######.#.#########.#.#.###.## +#.#.....#.#...#.#...#.#...#.....#.#.#.........#...#.#...#.#.#.#.#.#.#...#...#.#...#.......#.#.#...## +#.#.#####.#####.#.###.#.#########.###.#####.#.#.#.#.#####.###.#.#.#.###.#.#.#####.#.#####.#.#.#.#### +#.#.#...#.....#.#.#...#.........#.......#...#...#.#.....#.....#.#.#.#.#...#.......#.#.....#.#.#...## +#.#.#.#.#####.#.#.#.#####.#####.#########.###.#########.#.#######.#.#.#############.#######.#.###.## +#.#.#.#.#...#...#.#.#...#.#...#.#...#...#...#.#.....#...#.......#.#.#.......#.....#.#.......#...#.## +#.###.#.###.###.#.#.#.#.#.#.###.#.#.#.#.###.###.#.###.#########.#.#.#####.#.#.###.#.#.#########.#.## +#.#...#...#...#.#...#.#.#.#.......#...#...#.#...#...#.#...........#.......#.#...#.#...#.........#.## +#.#.#####.#.###.#####.#.#.###############.#.#.#####.#.###.#################.#.#.#######.#########.## +#...#...#.#...#.#.....#...#.......#.......#.#.#.#...#...#.......#...#...#...#.#...#.....#.......#.## +#.###.#.#.#.#.#.#.#######.#.#####.#.#####.#.#.#.#.#####.#########.#.###.#.###.###.#.#####.#####.#.## +#.#...#.#.#.#.....#.....#.#.....#.#.#...#...#...#...#...#...#.....#...#.#...#.#...#.........#.#.#.## +#.###.###.#######.#.###.#######.#.###.#.#.#####.###.#.###.#.#.#######.#.###.###.###########.#.#.#### +#...#...#.....#...#...#.....#...#...#.#.#.#...#.#.#...#...#...#...#...#...#.#...#.....#...#...#...## +###.###.#####.###.###.###.###.#####.#.#.###.#.#.#.#####.#.#####.###.#####.#.#.###.###.#.#.###.###.## +#.#.....#...#...#...#...#.....#...#.#.#.#...#...#...#...#.#...#.....#.....#.#...#...#...#.#...#...## +#.#####.#.#####.#.#####.#########.#.#.#.#.#######.#.#.###.###.#.#####.#####.###.###.#####.#####.#.## +#...#...#.....#.#.#.....#.........#...#.#...#.....#...#...#...#.....#.#...#.#.....#...#.........#.## +#.###.#####.#.#.###.#######.#.#########.###.###########.###.#######.#.#.#.#.#.#####.#.###########.## +#...#.#...#.#.#.....#.....#.#.......#.#...#.#...#.....#...#.....#...#...#.....#...#.#.........#...## +#.#.#.#.#.###.#######.###.#######.#.#.###.#.#.#.#.###.###.#.###.#.#############.#.###########.#.#### +#.#.....#.............#...........#.....#.....#...#.......#...#.................#.............#..E## +#################################################################################################### +####################################################################################################