Hard
There is an 8 x 8
chessboard containing n
pieces (rooks, queens, or bishops). You are given a string array pieces
of length n
, where pieces[i]
describes the type (rook, queen, or bishop) of the ith
piece. In addition, you are given a 2D integer array positions
also of length n
, where positions[i] = [ri, ci]
indicates that the ith
piece is currently at the 1-based coordinate (ri, ci)
on the chessboard.
When making a move for a piece, you choose a destination square that the piece will travel toward and stop on.
(r, c)
to the direction of (r+1, c)
, (r-1, c)
, (r, c+1)
, or (r, c-1)
.(r, c)
to the direction of (r+1, c)
, (r-1, c)
, (r, c+1)
, (r, c-1)
, (r+1, c+1)
, (r+1, c-1)
, (r-1, c+1)
, (r-1, c-1)
.(r, c)
to the direction of (r+1, c+1)
, (r+1, c-1)
, (r-1, c+1)
, (r-1, c-1)
.You must make a move for every piece on the board simultaneously. A move combination consists of all the moves performed on all the given pieces. Every second, each piece will instantaneously travel one square towards their destination if they are not already at it. All pieces start traveling at the 0th
second. A move combination is invalid if, at a given time, two or more pieces occupy the same square.
Return the number of valid move combinations.
Notes:
Example 1:
Input: pieces = [“rook”], positions = [[1,1]]
Output: 15
Explanation: The image above shows the possible squares the piece can move to.
Example 2:
Input: pieces = [“queen”], positions = [[1,1]]
Output: 22
Explanation: The image above shows the possible squares the piece can move to.
Example 3:
Input: pieces = [“bishop”], positions = [[4,3]]
Output: 12
Explanation: The image above shows the possible squares the piece can move to.
Constraints:
n == pieces.length
n == positions.length
1 <= n <= 4
pieces
only contains the strings "rook"
, "queen"
, and "bishop"
.1 <= xi, yi <= 8
positions[i]
is distinct.import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
@SuppressWarnings("unchecked")
public class Solution {
// 0: rook, queen, bishop
private int[][][] dirs = {
{ {-1, 0}, {1, 0}, {0, -1}, {0, 1}},
{ {-1, 0}, {1, 0}, {0, -1}, {0, 1}, {1, 1}, {-1, -1}, {-1, 1}, {1, -1}},
{ {1, 1}, {-1, -1}, {-1, 1}, {1, -1}}
};
public int countCombinations(String[] pieces, int[][] positions) {
ArrayList<int[]>[] endPosition = new ArrayList[pieces.length];
for (int i = 0; i < pieces.length; i++) {
endPosition[i] = new ArrayList<>();
}
for (int i = 0; i < pieces.length; i++) {
positions[i][0]--;
positions[i][1]--;
endPosition[i].add(positions[i]);
int dirIndex = 0;
switch (pieces[i]) {
case "rook":
dirIndex = 0;
break;
case "queen":
dirIndex = 1;
break;
case "bishop":
dirIndex = 2;
break;
default:
break;
}
for (int[] d : dirs[dirIndex]) {
int r = positions[i][0];
int c = positions[i][1];
while (true) {
r += d[0];
c += d[1];
if (r < 0 || r >= 8 || c < 0 || c >= 8) {
break;
}
endPosition[i].add(new int[] {r, c});
}
}
}
return dfs(positions, endPosition, new int[pieces.length], 0);
}
private int dfs(int[][] positions, ArrayList[] stop, int[] stopIndex, int cur) {
if (cur == stopIndex.length) {
int[][] p = new int[positions.length][2];
for (int i = 0; i < p.length; i++) {
p[i] = new int[] {positions[i][0], positions[i][1]};
}
return check(p, stop, stopIndex);
}
int res = 0;
for (int i = 0; i < stop[cur].size(); i++) {
stopIndex[cur] = i;
res += dfs(positions, stop, stopIndex, cur + 1);
}
return res;
}
private int check(int[][] positions, ArrayList<int[]>[] stop, int[] stopIndex) {
boolean keepGoing = true;
while (keepGoing) {
keepGoing = false;
for (int i = 0; i < positions.length; i++) {
int diff = stop[i].get(stopIndex[i])[0] - positions[i][0];
if (diff > 0) {
keepGoing = true;
positions[i][0]++;
} else if (diff < 0) {
keepGoing = true;
positions[i][0]--;
}
diff = stop[i].get(stopIndex[i])[1] - positions[i][1];
if (diff > 0) {
keepGoing = true;
positions[i][1]++;
} else if (diff < 0) {
keepGoing = true;
positions[i][1]--;
}
}
Set<Integer> seen = new HashSet<>();
for (int[] position : positions) {
int key = position[0] * 100 + position[1];
if (seen.contains(key)) {
return 0;
}
seen.add(key);
}
}
return 1;
}
}