Проверка (успех)

This commit is contained in:
Dima 2026-05-24 20:40:20 +03:00
parent 9395b9807c
commit 7e01d972c1
11 changed files with 395 additions and 13 deletions

View File

@ -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})")
# Проверяем, есть ли выход
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)
@ -873,7 +887,11 @@ class ExperimentRunner:
def save_to_csv(self, filename="experiment_results.csv"):
import csv
with open(filename, 'w', newline='', encoding='utf-8') as csvfile:
if not self.results:
print("Нет результатов для сохранения")
return
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} не создан")
def print_summary(self):
print("СВОДНАЯ СТАТИСТИКА ЭКСПЕРИМЕНТОВ")
@ -990,7 +1014,16 @@ 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()

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 KiB

View File

@ -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
1 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
2 tiny_simple (10x10) BFS (Поиск в ширину) 5 0.10344001930207014 0.0868999632075429 0.15590002294629812 28.0 28 28 19.0 19 19 True
3 tiny_simple (10x10) DFS (Поиск в глубину) 5 0.07182001136243343 0.05929998587816954 0.08929998148232698 28.0 28 28 19.0 19 19 True
4 tiny_simple (10x10) A Star 5 0.18986002542078495 0.1583000412210822 0.2394000766798854 28.0 28 28 19.0 19 19 True
5 tiny_simple (10x10) Дейкстра (Dijkstra) 5 0.2083600265905261 0.1431000418961048 0.3237000200897455 28.0 28 28 19.0 19 19 True
6 small_empty (20x20) BFS (Поиск в ширину) 5 1.2823000084608793 1.1743999784812331 1.4915000647306442 400.0 400 400 39.0 39 39 True
7 small_empty (20x20) DFS (Поиск в глубину) 5 0.9971400257200003 0.9467999916523695 1.153100049123168 400.0 400 400 191.0 191 191 True
8 small_empty (20x20) A Star 5 2.6846999768167734 2.398099983111024 2.9609999619424343 400.0 400 400 39.0 39 39 True
9 small_empty (20x20) Дейкстра (Dijkstra) 5 2.510580001398921 2.1893999073654413 2.994599984958768 400.0 400 400 39.0 39 39 True
10 medium_dfs (30x30) BFS (Поиск в ширину) 5 0.6412999937310815 0.5982000147923827 0.7941999938338995 171.0 171 171 105.0 105 105 True
11 medium_dfs (30x30) DFS (Поиск в глубину) 5 0.35470002330839634 0.34390005748718977 0.37720007821917534 110.0 110 110 105.0 105 105 True
12 medium_dfs (30x30) A Star 5 0.8171399822458625 0.7591999601572752 0.8969999616965652 141.0 141 141 105.0 105 105 True
13 medium_dfs (30x30) Дейкстра (Dijkstra) 5 0.9974599815905094 0.8565000025555491 1.2263000244274735 171.0 171 171 105.0 105 105 True
14 medium_complex (40x40) BFS (Поиск в ширину) 5 2.802439988590777 2.5909000542014837 3.390899975784123 614.0 614 614 373.0 373 373 True
15 medium_complex (40x40) DFS (Поиск в глубину) 5 1.8086799886077642 1.4740999322384596 2.945499960333109 397.0 397 397 373.0 373 373 True
16 medium_complex (40x40) A Star 5 3.598040039651096 3.0396999791264534 4.724400001578033 569.0 569 569 373.0 373 373 True
17 medium_complex (40x40) Дейкстра (Dijkstra) 5 3.372700000181794 2.929799957200885 4.301499924622476 614.0 614 614 373.0 373 373 True
18 large_dfs (50x50) BFS (Поиск в ширину) 5 2.029319992288947 1.6838000155985355 3.06529994122684 412.0 412 412 305.0 305 305 True
19 large_dfs (50x50) DFS (Поиск в глубину) 5 1.2084600050002337 1.1607999913394451 1.3439999893307686 314.0 314 314 305.0 305 305 True
20 large_dfs (50x50) A Star 5 2.5132999988272786 2.017199993133545 3.4434000262990594 366.0 366 366 305.0 305 305 True
21 large_dfs (50x50) Дейкстра (Dijkstra) 5 2.3565199924632907 1.976999919861555 3.297399962320924 412.0 412 412 305.0 305 305 True
22 very_large_dfs (100x100) BFS (Поиск в ширину) 5 28.673699987120926 26.941100019030273 32.57150005083531 3566.0 3566 3566 1813.0 1813 1813 True
23 very_large_dfs (100x100) DFS (Поиск в глубину) 5 15.021399967372417 14.021800016053021 16.41029992606491 1995.0 1995 1995 1813.0 1813 1813 True
24 very_large_dfs (100x100) A Star 5 20.14593998901546 19.036200013943017 22.409999975934625 3381.0 3381 3381 1813.0 1813 1813 True
25 very_large_dfs (100x100) Дейкстра (Dijkstra) 5 18.126800004392862 16.766700078733265 19.753700005821884 3566.0 3566 3566 1813.0 1813 1813 True
26 no_exit (20x20) BFS (Поиск в ширину) 5 0.003600004129111767 0.001300009898841381 0.011499971151351929 0.0 0 0 0.0 0 0 False
27 no_exit (20x20) DFS (Поиск в глубину) 5 0.0007200054824352264 0.000300002284348011 0.001900014467537403 0.0 0 0 0.0 0 0 False
28 no_exit (20x20) A Star 5 0.0005800044164061546 0.000300002284348011 0.001300009898841381 0.0 0 0 0.0 0 0 False
29 no_exit (20x20) Дейкстра (Dijkstra) 5 0.0006799818947911263 0.000300002284348011 0.0014998950064182281 0.0 0 0 0.0 0 0 False

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 KiB

View File

@ -0,0 +1,50 @@
##################################################
#S......#.....#...........#.........#...#.......##
#######.#####.#.#.#######.#.#######.#.###.#.###.##
#...#...#...#...#.....#.....#.....#.#.#...#.#...##
###.#.###.#.#.#######.#########.#.#.#.#.###.#.####
#...#.#...#.#.......#.#.......#.#.#.#.#...#.#...##
#.#.#.#.###.#######.#.#.#####.#.#.#.#.###.#.###.##
#.#.#.#.#.#.......#.#...#...#.#.#.#.#...#.#.#...##
#.###.#.#.#######.#######.#.#.#.#.#.#.#.#.#.######
#.#...#.#.......#...#...#.#...#.#.#.#.#...#.....##
#.#.###.#.#####.###.#.#.#.#######.#.###########.##
#.#.....#.#...#.#.#.#.#.#.......#.#.........#...##
#.#######.#.#.#.#.#.#.#.#######.#.#########.#.#.##
#.....#.....#.#.#.#.#.#.#.......#.........#.#.#.##
#.###.#####.#.#.#.#.#.#.#.#######.#######.#.#.####
#...#.....#.#.#...#...#...#.....#.#.......#.#...##
#.#.#####.###.###.#########.###.#.#.#######.#.#.##
#.#.#...#.....#.#.#.....#...#...#.#...#.....#.#.##
#.#.#.#########.#.#.###.#.###.#.#.###.#.#######.##
#.#.#...........#...#...#.#...#.#.#...#.#.....#.##
#.#.###.#######.#####.###.#.#####.#.###.###.#.#.##
#.#...#.......#...#.#...#.#.#.....#.....#...#.#.##
#.###.#######.###.#.###.#.#.#.###########.###.#.##
#...#...#...#.#.......#.#.#.#.....#.......#.#...##
###.###.#.#.#.#######.#.###.#####.#.#######.###.##
#...#...#.#...#...#...#.........#.#...#.....#...##
#.###.###.#####.#.###.#.#######.#.#.#.#####.#.####
#.#.#...#.#...#.#...#.#.#.....#.#.#.#...#...#.#.##
#.#.###.#.#.#.#.###.###.#.###.#.#.#####.#.#.#.#.##
#...#...#.#.#...#.#.....#...#.#.#.......#.#.#.#.##
#####.###.#.#####.#########.#.#.#########.#.#.#.##
#.....#.#...#.......#.....#.#.#.......#...#.#.#.##
#.#####.#.#########.#.#.#.#.#.#########.#.###.#.##
#.#...#.....#.......#.#.#.#.#.#.........#...#.#.##
#.#.#.#####.#.#######.#.###.#.#.#########.#.#.#.##
#...#.#...#...#.......#.....#...#...#...#.#.#...##
#.###.#.#.###.#.#############.###.###.#.#.#.###.##
#.#.#...#...#.#.#.....#.#...#.#...#...#.#.#.#...##
#.#.#######.#.#.###.#.#.#.#.#.###.#.###.###.#.####
#...#.....#.#.#...#.#...#.#.#.....#.#.#.#...#...##
###.#.#.###.#####.#.###.#.#.#######.#.#.#.#.###.##
#...#.#...#.....#.#.#...#.#.........#.....#.#.#.##
#.#######.###.###.#.#####.#####.###########.#.#.##
#.#.........#.#...#...#...#.....#.........#...#.##
#.#.#####.###.#.###.#.#.#########.#######.#.###.##
#...#.....#...#.#...#.#...#...#...#.....#.#.#...##
#####.#####.###.#####.###.#.#.#.#####.#.#.###.####
#.........#.............#...#.........#.#......E##
##################################################
##################################################

View File

@ -0,0 +1,40 @@
########################################
#S..........#.............#.......#...##
###########.#.#####.#####.#.#####.#.####
#.......#...#.....#.....#.#.#.#...#...##
#.#####.#.#######.#####.#.#.#.#.###.#.##
#.#...#.#.#.#.......#...#.#.#.....#.#.##
#.#.#.#.#.#.#.#######.###.#.#####.###.##
#.#.#.#.#.#...#.......#...#.....#.....##
#.#.#.#.#.#####.#######.#######.#####.##
#.#.#.#.#.....#.#.....#.........#.#...##
#.#.#.#######.#.#####.###########.#.####
#...#.......#...#.....#...........#...##
#######.###.#####.#####.#########.###.##
#.......#.......#.....#...#.....#...#.##
#.#############.#####.###.#.#######.#.##
#.#...........#...#...#...#...#.....#.##
#.#.#########.###.#.#.#.###.#.#.#.###.##
#.#.....#...#.#.....#.#...#.#.#.#.#...##
#.#####.###.#.###########.###.#.###.####
#.......#...#.#.........#.....#...#...##
#.#######.###.#.#####.###.#######.###.##
#...#.......#.#...#.#.#...#.......#...##
###.#######.#.###.#.#.#.###.#######.####
#.#.......#.#.....#.#...#.#.......#.#.##
#.#######.#.#######.#####.#######.#.#.##
#.......#...#.....#.........#...#.#.#.##
#.#####.###.###.#.###.#####.#.###.#.#.##
#.#...#...#.....#.#...#...#...#...#.#.##
#.###.#.#########.#.###.#####.#.###.#.##
#.#...#.........#...#.........#...#.#.##
#.#.###########.#####.###########.#.#.##
#.#...........#.....#.#...#.....#...#.##
#.#######.#.###.#####.#.#.#####.#####.##
#.#.......#.#...#...#...#.#.....#.....##
#.#.#######.#.###.#.#####.#.###.###.#.##
#...#.....#.#.....#...#...#...#...#.#.##
#####.###.#.#######.###.#####.###.###.##
#.......#.........#...........#......E##
########################################
########################################

View File

@ -0,0 +1,30 @@
##############################
#S....#.........#...........##
#####.#.#.#####.#.#########.##
#...#.#.#.#.....#.....#...#.##
#.###.###.#.#########.#.#.#.##
#.#...#...#.#.......#.#.#.#.##
#.#.###.#####.#####.#.#.#.#.##
#.#.#...#...#.#...#.#.#.#.#.##
#.#.###.#.#.#.#.###.#.#.###.##
#.#...#...#.#.#.#...#.#...#.##
#.###.#.###.#.#.#.#.#.###.#.##
#...#.#.#.#.#.#.#.#.#.....#.##
#.###.#.#.#.#.#.#.#.#####.#.##
#.....#...#.....#.#.#.....#.##
#.#####.#######.#.###.#####.##
#.#...#.#...#...#...#.#.#...##
#.#.#.###.#.#.#####.#.#.#.#.##
#...#...#.#.#...#.#.#.#.#.#.##
#######.#.#.###.#.#.#.#.#.#.##
#.....#...#...#...#.....#.#.##
#.###.#######.###########.#.##
#.#.......#...#.......#...#.##
###.#.#####.###.#####.#.######
#...#.#...#.#.......#.#.....##
#.#####.#.#.#######.#.###.#.##
#.....#.#.#.#.....#.#...#.#.##
#.###.#.#.#.#.###.#.###.###.##
#...#...#.....#.....#......E##
##############################
##############################

View File

@ -0,0 +1,20 @@
####################
#S..#.............##
###.#.###########.##
#.#.#.#.........#.##
#.#.#.###.###.###.##
#.#.#...#...#.#...##
#.#.###.###.#.#.#.##
#.#.#.....#.#.#.#.##
#.#.#####.###.#.####
#.#.....#.#...#...##
#.#####.#.#.#####.##
#.#...#.#.#...#...##
#.#.#.#.#.###.#.####
#...#...#...#.#...##
#.#########.#.###.##
#.....#...#...#...##
#####.#.#.#####.#.##
#.......#.......####
####################
####################

View File

@ -0,0 +1,20 @@
S...................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
...................E

View File

@ -0,0 +1,10 @@
S.########
...#######
#...######
##...#####
###...####
####...###
#####...##
######...#
#######...
########.E

View File

@ -0,0 +1,100 @@
####################################################################################################
#S#...............#.....#.....#.....#.......#...#.........#...#...#.......................#.....#.##
#.#######.#########.#.#.###.#.#.###.#.#.###.###.#.#.#####.#.###.#.#.#########.#####.#####.###.#.#.##
#.......#.#.........#.#.....#.#...#.#.#.#.#...#...#.#.....#.....#...#.......#.#.....#...#...#.#.#.##
#######.#.#.#########.#######.###.#.###.#.###.#####.#####.#.#######.#.###.###.#######.#.###.#.#.#.##
#...#...#...#...#.....#.....#...#.#.....#...#.....#.....#.#...#...#...#...#...#.......#.#.#...#...##
#.#.#.#####.#.#.#.#####.###.###.#.#########.#####.#####.#.#####.#.#####.###.###.#######.#.#######.##
#.#.#.....#.#.#.#.......#.#.#.#...#...#.........#.......#.......#...#.#.#...#...#...#.#.#.........##
#.#.#####.###.#.#####.###.#.#.#####.#.#.#.#########################.#.#.#.###.###.#.#.#.#######.####
#.#.....#.#...#.....#.....#.#.......#.#.#.#...#...........#.....#...#...#.........#...#.......#...##
#.#####.#.#.#######.#####.#.###.#####.###.#.#.#.###.#####.#.#.###.###.#################.#####.###.##
#.#...#...#.#.#.....#.....#...#.#...#.....#.#...#...#...#...#.#...#.#...#.#...#...#...#.....#.#...##
#.###.#####.#.#.#######.#####.#.###.#####.#.#####.#####.#####.#.###.###.#.#.#.#.#.#.#.###.###.######
#.......#...#.#.......#.....#.#...#.......#.....#.#...#.......#.#.....#...#.#.#.#.#.#.#...#...#...##
#######.#.#.#.#######.#######.###.#.###########.#.#.#.#.#######.#.###.###.#.#.#.#.#.#.#####.###.#.##
#.....#.#.#.#.................#...#.#.........#.#...#.#.....#.#.#...#.#...#.#.#.#...#...#...#...#.##
#####.#.#.#.###################.###.#.###.#####.#####.#####.#.#.#####.#.###.#.#.#######.#.#.#.###.##
#.....#.#.#...........#...#.....#.#...#...#...#.....#.#...#...#.....#...#...#.#.#.#.....#.#.#.#...##
#.#####.#########.###.#.#.#.#####.###.#####.#.#####.#.#.#.###.#####.#.###.###.#.#.#.#####.###.#.####
#.#...#.#...#...#.#...#.#.#.....#...#.#.....#.......#.#.#.#.#.#...#.#...#.#.#...#.#...#.......#...##
#.#.#.#.#.#.#.#.#.#.###.#.#.###.#.###.#.#############.#.#.#.#.#.###.###.#.#.#####.###.#.#########.##
#.#.#.#...#...#.#.#.....#.#.#...#...#.#...#.....#.....#.#.#.....#...#...#.#.......#...#.#.....#...##
#.#.#.#########.#########.#.#.#####.#.###.#####.#.###.#.#.#######.#######.#.###.#.#.###.#.###.#.####
#...#.........#.#.......#.#.#.....#.#.#.#.....#.#...#.#.#.......#.......#.#.#...#.#.#...#.#...#...##
#.#######.#####.#.#####.#.#######.#.#.#.#####.#.###.#.#.#######.#######.#.###.###.#.#####.#.###.#.##
#.....#.#.#...#...#...#...#...#...#...#.....#...#.#.#.#.#.....#...#...#...#...#...#.#.....#.#.#.#.##
#####.#.#.#.#.#####.#######.#.#.###.###.###.###.#.#.###.#####.#.#.###.#####.#######.#.#####.#.#.#.##
#...#.#.#...#.....#.........#...#.#.....#...#...#.#.....#...#.#.#.#...#.#...#.....#...#.#...#...#.##
#.#.#.#.#####.###.#######.#######.#.#####.###.###.#######.#.#.#.#.#.#.#.#.#.#.###.#####.#.#######.##
#.#.#...#...#.#.......#...#.....#...#...#...#...#.........#...#.#...#.#.#.#.....#.......#...#.....##
#.#####.#.#.#.#######.#.###.#.#.#.###.#.#######.#.###########.#.#####.#.#.#######.#####.###.#.###.##
#.......#.#.#...#...#...#...#.#.#...#.#.......#.#...#.......#.#...#...#.....#...#.#...#.#...#.#...##
#.#########.###.#.###########.###.###.#######.#.###.#####.#.#.###.#.#########.#.#.#.#.###.###.#.####
#...#.........#.#.............#...#...#.......#...#.#...#.#.#.#.#.#...........#.#...#.#...#...#...##
###.#.#.###.###.#.#.###########.###.###.#########.#.#.#.#.###.#.#.#############.#.###.#.#####.###.##
#...#.#.#...#...#.#...#.....#...#...#.#.#.........#...#.#...#...#.#.......#.....#...#.#.#.....#.#.##
#.#####.#.###.#######.#.###.#.###.###.#.#.#############.###.###.#.#.#####.#.#####.###.#.###.###.#.##
#.#.....#...#.....#...#.#.#.#...#.....#...#.............#.....#.#...#...#.#.....#.#...#.....#...#.##
#.#.#.#####.#####.#.###.#.#.###.#####.#####.###.#########.#####.#####.#.#.#####.###.###########.#.##
#.#.#.#...#...#...#...#...#...#.#...#.#.....#...#.....#.....#...#.....#.#.#...#...#.#...#.......#.##
#.###.#.#.#.###.###.#.###.###.#.###.#.#######.###.#.#.#####.#.###.#####.#.#.#####.#.#.#.#.#.#####.##
#.....#.#.#.#...#...#.....#...#.....#.........#...#.#...#...#.#.#.#...#...#.........#.#...#.......##
#######.#.#.#.#############.#.#####.###############.###.#.#.#.#.#.#.#.#############.#.##############
#.......#.#.#.#...#.........#.#...#.......#.....#...#.#.#.#.#.#.#.#.#.......#...#...#...#.......#.##
###.#######.#.#.#.#.#########.###.#######.#.#.#.#.###.#.#.#.#.#.#.#.#######.#.#.###.###.#.#####.#.##
#...#.....#.#...#.#...#...#.#...#...#.....#.#.#...#.....#.#.#...#...#.....#...#...#.#...#...#...#.##
#.###.###.#.#####.###.#.#.#.###.###.#.#######.#####.#####.#####.#####.###########.#.#.#####.###.#.##
#.....#.#...#...#...#...#.#...#.#...#...#...#.#...#.#.....#...#.#.....#...........#.#.....#...#...##
#.#####.#####.#.###.#####.#.#.#.#.#.###.#.#.#.#.###.###.#.#.#.#.#.###.#.#########.#######.#.#.######
#.#...#.......#...#.#...#.#.#.....#.#...#.#...#.........#.#.#...#.#...#...#.......#.....#.#.#.....##
#.#.#.###.#######.#.#.#.#.#########.#.###.###.#######.#####.#####.#.#####.#.#####.#.###.#.#.#####.##
#...#.....#.#.....#.#.#.#.#.....#...#.....#...#.....#.#.....#.....#.#...#.#.#...#.#.#.#.#.#...#...##
###########.#.#####.#.#.#.#.###.#######.#####.#.###.###.#####.#.###.###.#.#.#.#.#.#.#.#.#.#.###.#.##
#.#...#.....#.#.#...#.#.#.#...#.........#...#.#.#.#...#.#.....#.#...#...#.#.#.#.#.#.#.#...#.#...#.##
#.#.#.#.#.###.#.#.#.#.#.#.###.###########.#.#.#.#.###.#.###.###.#.###.#.#.###.#.#.#.#.#######.###.##
#.#.#...#.....#.#.#.#.#.#.........#.......#.#.#.#...#.#...#.#...#.....#.#.....#.#.#.#.........#...##
#.#.###########.#.###.#.###########.#######.#.#.#.###.###.###.#########.#######.###.#.#####.#####.##
#.#.....#...#...#.....#.........#...#...#...#.#.#.#.....#...#.#.....#.....#...#.....#...#.#.#...#.##
#.#####.#.#.###.###############.#.###.#.#.#####.#.#.#.#####.#.#.###.#.#####.#.#######.#.#.#.#.#.####
#.....#.#.#.....#.....#.......#.#.....#.#.......#.#.#.#...#.#...#...#...#...#.....#...#.#...#.#...##
#.#####.#.#####.#.#.#.#.#.#####.#######.#########.#.###.#.#.#.###.#####.#.#####.#.#.###.#####.###.##
#.#.....#.#.#...#.#.#...#.#...........#.#.....#...#.#...#...#.#.#.#.....#.#...#.#.#.#.#.....#...#.##
#.#.#####.#.#.#####.#####.#.#######.###.#.#.#.#.#.#.#.#######.#.#.#######.###.#.#.#.#.#####.###.#.##
#.#.#.....#...#.....#.#...#.....#...#...#.#.#.#.#.#...#.....#...#.............#.#.#...#...#.....#.##
#.#.#.#####.#####.###.#.#######.#.###.###.#.#.###.#####.###.#.#####.###########.#.###.###.#######.##
#.#...#...#.#.....#.#...#.....#.#...#.#.#.#.#...........#.#.#.#...#.#...........#.#.#...#.......#.##
#.#######.#.#.#####.#.###.###.#.#.###.#.#.#.#############.#.###.#.#.#.###########.#.###.#.#.#####.##
#.........#...#.....#.#...#.....#.#...#.#.#.#.......#.....#.#...#.#.#.......#...#.....#.#.#.#...#.##
#.#############.#.###.#.###########.###.#.#.#.#####.#.#.###.#.###.#.#####.#.###.#.#####.###.#.#.#.##
#...............#.#...#.............#.....#...#...#.#.#.#...#.#...#.#...#.#...#...#.....#...#.#.#.##
#.#####.#####.#####.###################.#####.#.#.#.###.#.###.#.#####.#.#.###.#####.#####.###.#.#.##
#.#...#.#.....#...#...#...............#.#...#...#.#...#...#...#.......#.#...#.#.....#.....#...#.#.##
###.#.###.###.#.#.###.#.#########.###.#.#.#.###.#####.###.#.###########.#####.#.#####.#####.###.#.##
#...#.#...#.#.#.#.....#.....#.....#.#.#.#.#...#.#...#...#...#.........#.......#.......#.....#...#.##
#.###.#.###.#.#.#############.#####.#.###.###.###.#.#.#.###.#.#######.#######.#######.#.#######.#.##
#.#...#.#...#.#.....#.......#...#...#.....#.#.....#.#.#...#.#.#.....#.#.......#.......#...#...#...##
#.#.###.#.#.#.#####.#.#####.###.#.#.#######.#######.#.###.#.#.#.#.#.#.#######.#.#########.#.#.###.##
#.#.....#.#...#.#...#.#...#.....#.#.#.........#...#.#...#.#.#.#.#.#.#...#...#.#...#.......#.#.#...##
#.#.#####.#####.#.###.#.#########.###.#####.#.#.#.#.#####.###.#.#.#.###.#.#.#####.#.#####.#.#.#.####
#.#.#...#.....#.#.#...#.........#.......#...#...#.#.....#.....#.#.#.#.#...#.......#.#.....#.#.#...##
#.#.#.#.#####.#.#.#.#####.#####.#########.###.#########.#.#######.#.#.#############.#######.#.###.##
#.#.#.#.#...#...#.#.#...#.#...#.#...#...#...#.#.....#...#.......#.#.#.......#.....#.#.......#...#.##
#.###.#.###.###.#.#.#.#.#.#.###.#.#.#.#.###.###.#.###.#########.#.#.#####.#.#.###.#.#.#########.#.##
#.#...#...#...#.#...#.#.#.#.......#...#...#.#...#...#.#...........#.......#.#...#.#...#.........#.##
#.#.#####.#.###.#####.#.#.###############.#.#.#####.#.###.#################.#.#.#######.#########.##
#...#...#.#...#.#.....#...#.......#.......#.#.#.#...#...#.......#...#...#...#.#...#.....#.......#.##
#.###.#.#.#.#.#.#.#######.#.#####.#.#####.#.#.#.#.#####.#########.#.###.#.###.###.#.#####.#####.#.##
#.#...#.#.#.#.....#.....#.#.....#.#.#...#...#...#...#...#...#.....#...#.#...#.#...#.........#.#.#.##
#.###.###.#######.#.###.#######.#.###.#.#.#####.###.#.###.#.#.#######.#.###.###.###########.#.#.####
#...#...#.....#...#...#.....#...#...#.#.#.#...#.#.#...#...#...#...#...#...#.#...#.....#...#...#...##
###.###.#####.###.###.###.###.#####.#.#.###.#.#.#.#####.#.#####.###.#####.#.#.###.###.#.#.###.###.##
#.#.....#...#...#...#...#.....#...#.#.#.#...#...#...#...#.#...#.....#.....#.#...#...#...#.#...#...##
#.#####.#.#####.#.#####.#########.#.#.#.#.#######.#.#.###.###.#.#####.#####.###.###.#####.#####.#.##
#...#...#.....#.#.#.....#.........#...#.#...#.....#...#...#...#.....#.#...#.#.....#...#.........#.##
#.###.#####.#.#.###.#######.#.#########.###.###########.###.#######.#.#.#.#.#.#####.#.###########.##
#...#.#...#.#.#.....#.....#.#.......#.#...#.#...#.....#...#.....#...#...#.....#...#.#.........#...##
#.#.#.#.#.###.#######.###.#######.#.#.###.#.#.#.#.###.###.#.###.#.#############.#.###########.#.####
#.#.....#.............#...........#.....#.....#...#.......#...#.................#.............#..E##
####################################################################################################
####################################################################################################