Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions HW2-PersonalPage/_config.yml

This file was deleted.

10 changes: 0 additions & 10 deletions HW2-PersonalPage/index.md

This file was deleted.

37 changes: 37 additions & 0 deletions HW4/chessQueenPosition/src/bitwise.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
def bitwise_n_queens(n):
bitmask = (1 << n) - 1

def count_solutions(row=0, cols=0, ascending_diag=0, descending_diag=0):
if row == n:
return 1

solutions_count = 0

all_attacks = cols | ascending_diag | descending_diag
available_positions = ~all_attacks & bitmask # 1 = available

while available_positions:
col_bit = available_positions & -available_positions # Rightmost available position
available_positions ^= col_bit

solutions_count += count_solutions(
row + 1,
cols | col_bit,
(ascending_diag | col_bit) << 1, # Diagonals shift as we move down
(descending_diag | col_bit) >> 1,
)

return solutions_count

return count_solutions()


def main():
BOARD_SIZE = 8
print("result:")
print(bitwise_n_queens(BOARD_SIZE))


if __name__ == "__main__":
main()

35 changes: 35 additions & 0 deletions HW4/chessQueenPosition/src/brute_force.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import itertools


def check_diagonal_attacks(queen_positions):
for i in range(len(queen_positions) - 1):
for j in range(i + 1, len(queen_positions)):
# Diagonal attack occurs when |row1 - row2| == |col1 - col2|
if abs(queen_positions[i][0] - queen_positions[j][0]) == abs(queen_positions[i][1] - queen_positions[j][1]):
return False
return True


def brute_force_n_queens(n):
solutions_count = 0
# Generate all collumn non-repeating permutations (queens will be in different rows anyway)
all_col_permutations = itertools.permutations(range(n))

for col_positions in all_col_permutations:
# Assign rows to each column and put results in the list
queen_positions = list(enumerate(col_positions))
if check_diagonal_attacks(queen_positions):
solutions_count += 1

return solutions_count


def main():
BOARD_SIZE = 8
print("result:")
print(brute_force_n_queens(BOARD_SIZE))


if __name__ == "__main__":
main()

26 changes: 26 additions & 0 deletions HW4/chessQueenPosition/src/complexity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Оценка сложности / Complexity analysis

## 1. Переборное решение / Brute-force solution

Сложность: O(N! * N^2)
Обоснование: N! перестановок * O(N^2) проверка корректности всех пар ферзей (N(N-1)/2 сравнений)

Complexity: O(N! * N^2)
Explanation: N! permutations * O(N^2) validity check of all queen pairs (N(N-1)/2 comparisons)

## 2. Рекурсивное решение / Recursive solution

Сложность: O(N! * N)
Обоснование: N! расстановок * O(N) проверка корректности для каждого нового ферзя

Complexity: O(N! * N)
Explanation: N! configurations * O(N) validity check for each new queen

## 3. Побитовое решение / Bitwise solution

Сложность: O(N!)
Обоснование: N! расстановок * O(1) битовые операции

Complexity: O(N!)
Explanation: N! configurations * O(1) bitwise operations

45 changes: 45 additions & 0 deletions HW4/chessQueenPosition/src/recursive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
def is_pos_safe(queen_positions, new_pos):
for q_pos in queen_positions:
# Diagonal attack occurs when |row1 - row2| == |col1 - col2|
if abs(q_pos[0] - new_pos[0]) == abs(q_pos[1] - new_pos[1]):
return False
return True


def recursive_n_queens(n, row=0, queen_positions=None, used_cols=None):
if queen_positions is None:
queen_positions = []
if used_cols is None:
used_cols = set()

if row == n:
return 1

solutions_count = 0

for col in range(n):
if col in used_cols:
continue

if is_pos_safe(queen_positions, [row, col]):
queen_positions.append([row, col])
used_cols.add(col)

solutions_count += recursive_n_queens(n, row + 1, queen_positions, used_cols)

# Backtrack
queen_positions.pop()
used_cols.remove(col)

return solutions_count


def main():
BOARD_SIZE = 8
print("result:")
print(recursive_n_queens(BOARD_SIZE))


if __name__ == "__main__":
main()