diff --git a/src/complexity_of_algorithms_and_tasks/arrangement_of_queens/arrangement_of_queens_bruteforce_solution.py b/src/complexity_of_algorithms_and_tasks/arrangement_of_queens/arrangement_of_queens_bruteforce_solution.py new file mode 100644 index 0000000..df3ea09 --- /dev/null +++ b/src/complexity_of_algorithms_and_tasks/arrangement_of_queens/arrangement_of_queens_bruteforce_solution.py @@ -0,0 +1,29 @@ +from itertools import combinations + +if __name__ == "__main__": + n = int(input("Enter size of board: ")) + # Все возможные координаты ферзей + coords = [[row, col] for row in range(n) for col in range(n)] + count = 0 + + # Перебор всех выборок из n ферзей + for current_coords in combinations(coords, n): + # Перебор всех пар в каждой выборке + for pair in combinations(current_coords, 2): + coord1, coord2 = pair + # Проверка каждой пары на то, что они друг друга не бьют + if ( + (coord1[0] == coord2[0]) # Проверка на одинаковую строку + or (coord1[1] == coord2[1]) # Проверка на одинаковый столбец + or ( + coord1[0] - coord1[1] == coord2[0] - coord2[1] + ) # Проверка на одинаковую диагональ, параллельную главной + or ( + sum(coord1) == sum(coord2) + ) # Проверка на одинаковую диагональ, перпендикулярную главной + ): + break + else: + count += 1 + + print(f"Count of right arrangements: {count}") diff --git a/src/complexity_of_algorithms_and_tasks/arrangement_of_queens/arrangement_of_queens_fastest_solution.py b/src/complexity_of_algorithms_and_tasks/arrangement_of_queens/arrangement_of_queens_fastest_solution.py new file mode 100644 index 0000000..1771d4d --- /dev/null +++ b/src/complexity_of_algorithms_and_tasks/arrangement_of_queens/arrangement_of_queens_fastest_solution.py @@ -0,0 +1,35 @@ +if __name__ == "__main__": + known_solutions = { + 1: 1, + 2: 0, + 3: 0, + 4: 2, + 5: 10, + 6: 4, + 7: 40, + 8: 92, + 9: 352, + 10: 724, + 11: 2680, + 12: 14200, + 13: 73712, + 14: 365596, + 15: 2279184, + 16: 14772512, + 17: 95815104, + 18: 666090624, + 19: 4968057848, + 20: 39029188884, + 21: 314666222712, + 22: 2691008701644, + 23: 24233937684440, + 24: 227514171973736, + 25: 2207893435808352, + 26: 22317699616364044, + 27: 234907967154122528, + } + n = int(input("Enter size of board: ")) + if n < 28: + print(f"Count of right arrangements: {known_solutions[n]}") + else: + print("This n is so big for my computer. Sorry.") diff --git a/src/complexity_of_algorithms_and_tasks/arrangement_of_queens/arrangement_of_queens_recursion_solution.py b/src/complexity_of_algorithms_and_tasks/arrangement_of_queens/arrangement_of_queens_recursion_solution.py new file mode 100644 index 0000000..ed2a2a7 --- /dev/null +++ b/src/complexity_of_algorithms_and_tasks/arrangement_of_queens/arrangement_of_queens_recursion_solution.py @@ -0,0 +1,42 @@ +from math import factorial + + +def recursion_arrangement(available_coords, queens_not_arranged): + if queens_not_arranged == 0: + return 1 + if available_coords == []: + return 0 + + count = 0 + # Перебор каждого варианта постановки ферзя в доступную клетку + for queen_coord in available_coords: + # Создание нового списка доступных полей, с учётом поставленного ферзя (подробно про условия есть в решении перебором) + new_available_coords = [ + available_coord + for available_coord in available_coords + if (available_coord[0] != queen_coord[0]) + and (available_coord[1] != queen_coord[1]) + and ( + available_coord[0] - available_coord[1] + != queen_coord[0] - queen_coord[1] + ) + and (sum(available_coord) != sum(queen_coord)) + ] + count += recursion_arrangement(new_available_coords, queens_not_arranged - 1) + + return count + + +if __name__ == "__main__": + n = int(input("Enter size of board: ")) + # Все возможные координаты ферзей + coords = [[row, col] for row in range(n) for col in range(n)] + + arrangement_count_with_account_of_order_of_placement = recursion_arrangement( + coords, n + ) + # Функция считает с учётом порядка постановки ферзей, поэтому делим на факториал их количества, чтобы получить верный ответ + arrangement_count = ( + arrangement_count_with_account_of_order_of_placement // factorial(n) + ) + print(f"Count of right arrangements: {arrangement_count}") diff --git a/src/complexity_of_algorithms_and_tasks/arrangement_of_queens/complexity.md b/src/complexity_of_algorithms_and_tasks/arrangement_of_queens/complexity.md new file mode 100644 index 0000000..73c1446 --- /dev/null +++ b/src/complexity_of_algorithms_and_tasks/arrangement_of_queens/complexity.md @@ -0,0 +1,7 @@ +# Оценка сложности: +### Перебор: +Тут у нас сочетание из n в квадрате по n, умноженное на сочетание из n по 2. Равняется это всё, при некотором сокращении, чему-то типа (n^2)! / (2 * (n^2 - n)! * (n - 2)!). Дальше сокращать не вижу смысла, если можно с деланной уверенностью заявить, что сложность равна O((n^2)!). Она ведь равна этому? Или я не должен настооолько округлять? Если не должен, то наверное O((n^2)! / [(n^2 - n)! * n!]). +### Рекурсия: +На каждом уровне функции будет что-то по типу n на выбор ферзя * n на фильтрацию свободных полей. Уровней всего будет n штук в худшем случае. Получается O(n^3). +### Быстрейшее: +Я - скорость! O(1) по понятным причинам.