From 774f87771be71eb9d2dc642000c937cf44232e37 Mon Sep 17 00:00:00 2001 From: ialina07 Date: Thu, 9 Oct 2025 20:55:50 +0000 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=D0=B0=20=D1=80=D0=B5=D1=88=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=B4=D0=B0=D1=87=D0=B8=20=D0=BE=20=D1=80=D0=B0=D1=81?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D0=B5=20=D1=84=D0=B5?= =?UTF-8?q?=D1=80=D0=B7=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/homework4-task_queens/queens_optimized.py | 70 +++++++++++++++++ src/homework4-task_queens/queens_perebor.py | 52 +++++++++++++ src/homework4-task_queens/queens_recursive.py | 75 +++++++++++++++++++ 3 files changed, 197 insertions(+) create mode 100644 src/homework4-task_queens/queens_optimized.py create mode 100644 src/homework4-task_queens/queens_perebor.py create mode 100644 src/homework4-task_queens/queens_recursive.py diff --git a/src/homework4-task_queens/queens_optimized.py b/src/homework4-task_queens/queens_optimized.py new file mode 100644 index 0000000..7af42cc --- /dev/null +++ b/src/homework4-task_queens/queens_optimized.py @@ -0,0 +1,70 @@ +def n_queens_bitmask(n): + """Самое быстрое решение с использованием битовых масок""" + if n < 1: + return 0 + + def backtrack(row=0, columns=0, diagonals1=0, diagonals2=0): + if row == n: + return 1 + + count = 0 + # Доступные позиции в текущей строке + available_positions = ((1 << n) - 1) & ~(columns | diagonals1 | diagonals2) + + while available_positions: + # Берем самую правую доступную позицию + position = available_positions & -available_positions + # Убираем ее из доступных + available_positions -= position + + count += backtrack( + row + 1, + columns | position, + (diagonals1 | position) << 1, + (diagonals2 | position) >> 1, + ) + + return count + + return backtrack() + + +def test_bitmask_basic(): + """Тест оптимизированного решения (bitmask)""" + print("ТЕСТИРОВАНИЕ BITMASK РЕШЕНИЯ") + print("=" * 50) + + # Известные значения для N ферзей + test_cases = [ + (1, 1), # [0] + (2, 0), # нет решений + (3, 0), # нет решений + (4, 2), # 2 решения + (5, 10), # 10 решений + (6, 4), # 4 решения + (7, 40), # 40 решений + (8, 92), # 92 решения + (9, 352), # 352 решения + (10, 724), # 724 решения + ] + + all_passed = True + + for n, expected in test_cases: + result = n_queens_bitmask(n) + + if result == expected: + print(f"✓ N={n}: {result} (ожидалось {expected})") + else: + print(f"✗ N={n}: {result} (ожидалось {expected})") + all_passed = False + + print("=" * 50) + print(f"РЕЗУЛЬТАТ: {'Все тесты пройдены' if all_passed else 'Есть ошибки'}") + + return all_passed + + +# Запуск теста +if __name__ == "__main__": + test_bitmask_basic() diff --git a/src/homework4-task_queens/queens_perebor.py b/src/homework4-task_queens/queens_perebor.py new file mode 100644 index 0000000..46c0598 --- /dev/null +++ b/src/homework4-task_queens/queens_perebor.py @@ -0,0 +1,52 @@ +import itertools + + +def is_valid_placement(positions): + """Проверяет, является ли расстановка ферзей корректной""" + n = len(positions) + for i in range(n): + for j in range(i + 1, n): + # Проверка на одну строку (невозможно в нашей модели) + # Проверка на одну диагональ + if abs(positions[i] - positions[j]) == abs(i - j): + return False + return True + + +def n_queens_placement(n): + """Перебор всех возможных расстановок""" + if n < 1 or n > 10: # Ограничение для перебора + return 0 + + count = 0 + # Генерируем все перестановки (каждый ферзь в своем столбце) + for permutation in itertools.permutations(range(n)): + if is_valid_placement(permutation): + count += 1 + return count + + +def test_placement_small(): + """Тестирование для маленьких N где перебор работает быстро""" + test_cases = { + 1: 1, # [0] + 2: 0, # нет решений + 3: 0, # нет решений + 4: 2, # [1,3,0,2] и [2,0,3,1] + 5: 10, # известное значение + 6: 4, # известное значение + } + + print("Тестирование переборного решения:") + print("N\tОжидаемо\tПолучено\tСтатус") + print("-" * 40) + + for n, expected in test_cases.items(): + if n <= 6: # Ограничиваем для скорости + result = n_queens_placement(n) + status = "✓" if result == expected else "✗" + print(f"{n}\t{expected}\t\t{result}\t\t{status}") + + +if __name__ == "__main__": + test_placement_small() diff --git a/src/homework4-task_queens/queens_recursive.py b/src/homework4-task_queens/queens_recursive.py new file mode 100644 index 0000000..504f4c8 --- /dev/null +++ b/src/homework4-task_queens/queens_recursive.py @@ -0,0 +1,75 @@ +def is_valid_recursive(board, row, col): + """Проверяет, можно ли поставить ферзя на позицию (row, col)""" + # Проверяем все предыдущие строки + for i in range(row): + # Проверка по вертикали и диагоналям + if board[i] == col or abs(board[i] - col) == abs(i - row): + return False + return True + + +def solve_n_queens_recursive(n, row=0, board=None, count=None): + """Рекурсивное решение с backtracking""" + if board is None: + board = [-1] * n + if count is None: + count = [0] + + if row == n: + # Найдена корректная расстановка + count[0] += 1 + return + + for col in range(n): + if is_valid_recursive(board, row, col): + board[row] = col + solve_n_queens_recursive(n, row + 1, board, count) + # Backtrack - не нужно явно сбрасывать, так как перезаписываем + + return count[0] + + +def n_queens_recursive(n): + """Обертка для рекурсивного решения""" + if n < 1: + return 0 + return solve_n_queens_recursive(n) + + +def test_n_queens_recursive_basic(): + """Тест рекурсивного решения на известных значениях""" + print("ТЕСТИРОВАНИЕ РЕКУРСИВНОГО РЕШЕНИЯ") + print("=" * 40) + + # Известные значения для N ферзей + test_cases = [ + (1, 1), # [0] + (2, 0), # нет решений + (3, 0), # нет решений + (4, 2), # 2 решения + (5, 10), # 10 решений + (6, 4), # 4 решения + (7, 40), # 40 решений + (8, 92), # 92 решения + ] + + all_passed = True + + for n, expected in test_cases: + result = n_queens_recursive(n) + + if result == expected: + print(f"✓ N={n}: {result} (ожидалось {expected})") + else: + print(f"✗ N={n}: {result} (ожидалось {expected})") + all_passed = False + + print("=" * 40) + print(f"РЕЗУЛЬТАТ: {'Все тесты пройдены' if all_passed else 'Есть ошибки'}") + + return all_passed + + +# Запуск теста +if __name__ == "__main__": + test_n_queens_recursive_basic()