Python provides binary operators for working with integers.
One can get the binary representation of an integer using an f-string.
print(f"{1:b}")
print(f"{4:b}")
print(f"{10:b}")
1
100
1010
5. Binary operators#
&
bitwise and:2 & 3 = 0
a, b = 2, 3
print(f"a : {a} : {a:b}")
print(f"b : {b} : {b:b}")
print(f"and : a & b : {a & b} : {a & b:b}")
print(f"or : a | b : {a | b} : {a | b:b}")
print(f"xor : a ^ b : {a ^ b} : {a ^ b:b}")
print(f"a ^ b : {a ^ b} : {a ^ b:b}")
a : 2 : 10
b : 3 : 11
and : a & b : 2 : 10
or : a | b : 3 : 11
xor : a ^ b : 1 : 1
a ^ b : 1 : 1
6. Queen#
class Queens:
def __init__(self, n):
self.n = n
rangen = range(n)
# Assign a unique int to each column and diagonal.
# columns: n of those, range(n).
# NW-SE diagonals: 2n-1 of these, i-j unique and invariant along
# each, smallest i-j is 0-(n-1) = 1-n, so add n-1 to shift to 0-
# based.
# NE-SW diagonals: 2n-1 of these, i+j unique and invariant along
# each, smallest i+j is 0, largest is 2n-2.
# For each square, compute a bit vector of the columns and
# diagonals it covers, and for each row compute a function that
# generates the possibilities for the columns in that row.
self.rowgenerators = []
for i in rangen:
rowuses = [(1 << j) | # column ordinal
(1 << (n + i-j + n-1)) | # NW-SE ordinal
(1 << (n + 2*n-1 + i+j)) # NE-SW ordinal
for j in rangen]
def rowgen(rowuses=rowuses):
for j in rangen:
uses = rowuses[j]
if uses & self.used == 0:
self.used |= uses
yield j
self.used &= ~uses
self.rowgenerators.append(rowgen)
# Generate solutions.
def solve(self):
self.used = 0
for row2col in conjoin(self.rowgenerators):
yield row2col
def printsolution(self, row2col):
n = self.n
assert n == len(row2col)
sep = "+" + "-+" * n
print(sep)
for i in range(n):
squares = [" " for j in range(n)]
squares[row2col[i]] = "Q"
print("|" + "|".join(squares) + "|")
print(sep)
Cell In[3], line 2
def __init__(self, n):
^
IndentationError: expected an indented block after class definition on line 1