From 8b87e428ccc50d608104d4c92e8f82e113b6bdc2 Mon Sep 17 00:00:00 2001 From: ada1ra Date: Thu, 9 Oct 2025 22:55:27 +0300 Subject: [PATCH 1/5] Add bruteforce solution --- src/hw_4-1_queen/hw_4-1_queen_bruteforce.py | 28 +++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/hw_4-1_queen/hw_4-1_queen_bruteforce.py diff --git a/src/hw_4-1_queen/hw_4-1_queen_bruteforce.py b/src/hw_4-1_queen/hw_4-1_queen_bruteforce.py new file mode 100644 index 0000000..8bbd384 --- /dev/null +++ b/src/hw_4-1_queen/hw_4-1_queen_bruteforce.py @@ -0,0 +1,28 @@ +import itertools + +def is_valid_bruteforce(board): + # проверяет, можно ли так поставить ферзей + n = len(board) + for i in range(n): + for j in range(i + 1, n): + # проверка на одну диагональ + if abs(i - j) == abs(board[i] - board[j]): + return False + return True + +def queens_bruteforce(n): + # перебор всех возможных расстановок + if n < 1 or n > 10: # ограничение из-за сложности + return 0 + + count = 0 + # генерируем все перестановки (каждый ферзь в уникальной строке и столбце) + for permutation in itertools.permutations(range(n)): + if is_valid_bruteforce(permutation): + count += 1 + return count + + +# тест +for n in range(1, 11): + print(f"n={n}: {queens_bruteforce(n)} решений") From a834c77f663285ae48acd0e2c50f2a05b441ee9a Mon Sep 17 00:00:00 2001 From: ada1ra Date: Thu, 9 Oct 2025 22:55:56 +0300 Subject: [PATCH 2/5] Add recursion (backtracking) solution --- src/hw_4-1_queen/hw_4-1_queen_backtracking.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/hw_4-1_queen/hw_4-1_queen_backtracking.py diff --git a/src/hw_4-1_queen/hw_4-1_queen_backtracking.py b/src/hw_4-1_queen/hw_4-1_queen_backtracking.py new file mode 100644 index 0000000..9894854 --- /dev/null +++ b/src/hw_4-1_queen/hw_4-1_queen_backtracking.py @@ -0,0 +1,33 @@ +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_recursive(n, row, board, solutions): + # рекурсивно находит все решения + if row == n: + solutions.append(board) + return + + for col in range(n): + if is_valid_recursive(board, row, col): + board[row] = col + # возвращаемся к 1 строке и смотрим следующий столбец + solve_recursive(n, row + 1, board, solutions) + +def queens_recursive(n): + # запускаем решение + if n < 1: + return 0 + + solutions = [] + board = [-1] * n # board[i] = столбец ферзя в строке i + solve_recursive(n, 0, board, solutions) + return len(solutions) + +# тест +for n in range(1, 11): + print(f"n={n}: {queens_recursive(n)} решений") From 3e21ea6a8d021a5003d292a18df422ab17ae7b19 Mon Sep 17 00:00:00 2001 From: ada1ra Date: Thu, 9 Oct 2025 22:56:12 +0300 Subject: [PATCH 3/5] Add the faster solution --- src/hw_4-1_queen/hw_4-1_queen_best.py | 41 +++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/hw_4-1_queen/hw_4-1_queen_best.py diff --git a/src/hw_4-1_queen/hw_4-1_queen_best.py b/src/hw_4-1_queen/hw_4-1_queen_best.py new file mode 100644 index 0000000..26eb6f7 --- /dev/null +++ b/src/hw_4-1_queen/hw_4-1_queen_best.py @@ -0,0 +1,41 @@ +def backtrack(row, columns, diagonal1, diagonal2): + if row == n: + return 1 + + count = 0 + for col in range(n): + # вычисляем номера диагоналей + d1 = row - col # диагональ \ + d2 = row + col # диагональ / + + # проверяем конфликты + if col in columns or d1 in diagonal1 or d2 in diagonal2: + continue + + # добавляем ферзя + columns.add(col) + diagonal1.add(d1) + diagonal2.add(d2) + + # рекурсивный вызов + count += backtrack(row + 1, columns, diagonal1, diagonal2) + + # убираем ферзя (откат) + columns.remove(col) + diagonal1.remove(d1) + diagonal2.remove(d2) + + return count + + +def queens_simple(n): + # рекурсивное решение с множествами + if n < 1: + return 0 + + return backtrack(0, set(), set(), set()) + + +# тест +for n in range(1, 11): + print(f"n={n}: {queens_simple(n)} решений") From 8ee3a38888933088b80bdb6d5fc454604bd3baea Mon Sep 17 00:00:00 2001 From: ada1ra Date: Thu, 9 Oct 2025 22:58:38 +0300 Subject: [PATCH 4/5] Add complexity.md with complexity assessment --- src/hw_4-1_queen/complexity.md | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/hw_4-1_queen/complexity.md diff --git a/src/hw_4-1_queen/complexity.md b/src/hw_4-1_queen/complexity.md new file mode 100644 index 0000000..4d206bd --- /dev/null +++ b/src/hw_4-1_queen/complexity.md @@ -0,0 +1,35 @@ +# Оценка сложности решений задачи о расстановке ферзей + +## 1. Переборное решение (bruteforce) + +**Сложность:** O(N! * N²) + +**Обоснование:** +- Генерируются все перестановки из N элементов: O(N!) +- Для каждой перестановки выполняется проверка валидности за O(N²) +- Проверка включает сравнение всех пар ферзей (N*(N-1)/2 сравнений) + +**Применение:** Только для очень маленьких N (N ≤ 10) + +## 2. Рекурсивное решение (backtracking) + +**Сложность:** O(N!) + +**Обоснование:** +- В худшем случае перебираются все возможные расстановки +- Отсечение невалидных ветвей сокращает перебор +- Фактическое количество рекурсивных вызовов меньше N! +- Проверка валидности за O(N) на каждом уровне + +**Применение:** Работает для N ≤ 15-20 за нормальное время + +## 3. Простое решение с множествами + +**Сложность:** O(N!) + +**Обоснование:** +- Теоретическая сложность остается O(N!) +- Проверка конфликтов через множества работает за O(1) +- Немного медленнее из-за работы с множествами + +**Применение:** Работает для N ≤ 15-18 From dc7532fbcd5cdf8b1fb4ab0915c16a2ea9cf79e5 Mon Sep 17 00:00:00 2001 From: ada1ra Date: Thu, 9 Oct 2025 23:05:50 +0300 Subject: [PATCH 5/5] Add pyproject.toml --- pyproject.toml | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b477208 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,78 @@ +# ruff.toml +target-version = "py311" +line-length = 100 + +# включить все основные правила +select = [ + "E", # pycodestyle errors + "W", # pycodestyle warnings + "F", # Pyflakes + "I", # isort + "N", # pep8-naming + "UP", # pyupgrade + "YTT", # flake8-2020 + "S", # flake8-bandit + "A", # flake8-builtins + "COM", # flake8-commas + "C4", # flake8-comprehensions + "DTZ", # flake8-datetimez + "T10", # flake8-debugger + "EM", # flake8-errmsg + "EXE", # flake8-executable + "ISC", # flake8-implicit-str-concat + "ICN", # flake8-import-conventions + "G", # flake8-logging-format + "INP", # flake8-no-pep420 + "PIE", # flake8-pie + "T20", # flake8-print + "PYI", # flake8-pyi + "PT", # flake8-pytest-style + "Q", # flake8-quotes + "RSE", # flake8-raise + "RET", # flake8-return + "SLF", # flake8-self + "SIM", # flake8-simplify + "TID", # flake8-tidy-imports + "TCH", # flake8-type-checking + "INT", # flake8-gettext + "ARG", # flake8-unused-arguments + "FBT", # flake8-boolean-trap + "B", # flake8-bugbear + "AIR", # flake8-airflow + "PERF", # flake8-perflint +] + +# игнорировать правила +ignore = [ + "E501", # line too long - handled by formatter + "S101", # assert used - ok in tests + "T201", # print found - sometimes needed + "COM812", # trailing comma missing - not always required +] + +# настройки для конкретных файлов +[per-file-ignores] +"__init__.py" = ["F401"] # Unused imports allowed in __init__.py +"tests/**" = ["S101", "SLF001"] # Allow assert and self in tests +"**/migrations/**" = ["ALL"] # Ignore all in migrations + +# настройки форматтера +[format] +indent-style = "space" +quote-style = "double" +skip-magic-trailing-comma = false +line-ending = "auto" + +# настройки для конкретных правил +[flake8-quotes] +docstring-quotes = "double" +inline-quotes = "double" + +[flake8-tidy-imports] +ban-relative-imports = "all" + +[isort] +known-first-party = ["myapp"] +lines-after-imports = 2 +combine-as-imports = true +split-on-trailing-comma = true