If bishop X
, Y
& Z
are all on a diagonal, X
can capture Y
, Y
can capture both X
& Z
, and Z
can capture Y
. All 3 are unsafe. If the problem has no requirement to determine exactly which bishop captures which bishops -- just determine the number which could be captured -- then you don't need to move each bishop along the each of the four dx, dy in moves
directions until it encounters another bishop. That is just mechanical busy work.
A bishop X
is unsafe if any other bishop Y
satisfies either (or both) of the following:
bishop[X][0] + bishop[X][1] == bishop[Y][0] + bishop[Y][1]
, or
bishop[X][0] - bishop[X][1] == bishop[Y][0] - bishop[Y][1]
.
You can partition the bishops according to diagonals. If two or more bishops are on the same diagonal, all of those bishops are unsafe.
Note that the size
of the board is unnecessary.
The following is a review of and improvement upon @RootTwo's answer.
A vanilla dictionary is a poor choice for nwse
and nesw
. That requires you check if the diagonal index has already been created in the dictionary, to determine whether to store a new list in the dictionary, or to appended to the existing list. A better option is to use defaultdict
, which automatically creates the entry using the provided default if that entry is not present:
from collections import defaultdict
nwse = defaultdict(list)
nesw = defaultdict(list)
The bishops
is already a collection of tuple
coordinates. Creating your own tuples in = [(row,col)]
and .append((row,col))
is creating new objects identical to the existing ones in everything except identity. There is no need to pollute the memory with these new tuples; just reuse the existing ones:
for bishop in bishops:
row, col = bishop
nwse[row + col].append(bishop)
nesw[row - col].append(bishop)
The for k,v in nwse.items():
loop never uses the dictionary key value (k
) in the body of the loop. It makes no sense to extract it from the dictionary. Just loop over the values()
of the dictionaries:
in_danger = set()
for v in nwse.values():
if len(v) > 1:
in_danger.update(v)
for v in nesw.values():
if len(v) > 1:
in_danger.update(v)
The problem asks for "how many bishops are unsafe", not the number that are safe. So the output should be:
print(len(in_danger))
Finally, follow the PEP-8 standards. Specifically, you need a space after all of your commas.
from collections import defaultdict
bishops = [(0, 0),
(1, 1),
(0, 2),
(1, 3),
(2, 0),
(2, 2)]
nwse = defaultdict(list)
nesw = defaultdict(list)
for bishop in bishops:
row, col = bishop
nwse[row + col].append(bishop)
nesw[row - col].append(bishop)
in_danger = set()
for v in nwse.values():
if len(v) > 1:
in_danger.update(v)
for v in nesw.values():
if len(v) > 1:
in_danger.update(v)
print(len(in_danger))