-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqueens_v3.py
102 lines (81 loc) · 2.67 KB
/
queens_v3.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# %%
import random
import numpy as np
import time
import itertools
def timeit(f):
def timed(*args, **kw):
ts = time.time()
result = f(*args, **kw)
te = time.time()
print("func:%r args:[%r, %r] took: %2.4f sec" %
(f.__name__, args, kw, te - ts))
return result
return timed
class queens:
def __init__(self, n, fixed_position):
self.fixed_position = fixed_position
self.n = n
self.attempt = 0
self.attempts_max = 100
self.solved = False
self.board = np.zeros((self.n, self.n))
self.boardtext = ""
print("Class queens is initialized")
def place(self):
# Count attempt
self.attempt += 1
# Reset queens position
self.queens_positions = [self.fixed_position]
# Generate rows and cols
rows = list(range(self.n))
rows.remove(self.fixed_position[0])
cols = list(range(self.n))
cols.remove(self.fixed_position[1])
# Iterate over rows
for row in rows:
# Validate
self.validate(row, cols)
# Remove from colums if validated (there is a new queens position)
col = self.queens_positions[-1][1]
if col in cols:
cols.remove(col)
def validate(self, row, cols):
for col in cols:
# Get all combinations with previous positions
comb = list(itertools.combinations(
self.queens_positions + [(row, col)], 2))
# Check if is not on a diagonal with another queen
valid = not any(
list(map(lambda x: self.checkSameDiag(*x), comb)))
# If position is not valid, then repeat random choice, otherwise add this position to list
if valid:
self.queens_positions.append((row, col))
break
def getBoard(self):
# Convert array fo tuples into array
a = np.array([*self.queens_positions])
# Place 2 for queens positions
self.board[a[:, 0], a[:, 1]] = 2
# Check if solved
self.solved = np.count_nonzero(self.board == 2) == self.n
@staticmethod
def checkSameDiag(pos1, pos2):
# Condition to check if the both the elements are in same diagonal of a matrix
I, J = pos1
P, Q = pos2
if abs(P-I) == abs(Q-J):
return True
else:
return False
if __name__ == "__main__":
q = queens(8, (0, 0))
while q.attempt <= q.attempts_max:
q.place()
if len(q.queens_positions) == q.n:
break
q.getBoard()
print(q.board)
print(q.solved)
print(q.attempt)
# %%