Q2 - BFS
public static void main(String[] args) {
String[] B1 = {".##.#", "#.#..", "#...#", "#.##."};
Arrays.stream(getCounts(B1)).forEach(e -> System.out.print(e + ","));
System.out.println();
String[] B2 = {".#..#", "##..#", "...#."};
Arrays.stream(getCounts(B2)).forEach(e -> System.out.print(e + ","));
System.out.println();
String[] B3 = {"##.", "#.#", ".##"};
Arrays.stream(getCounts(B3)).forEach(e -> System.out.print(e + ","));
System.out.println();
String[] B4 = {"...", "...", "..."};
Arrays.stream(getCounts(B4)).forEach(e -> System.out.print(e + ","));
}
public static int[] getCounts(String[] B) {
int[] result = new int[3]; //The key point is having only 3 different ships and the sizes are 1,2,3 regardless of the shape.
char[][] map = new char[B.length][B[0].length()]; //create a 2 dimension array like a standard matrix problem
for (int row = 0; row < B.length; row++) { //string is like charArray
for (int col = 0; col < B[row].length(); col++) {
map[row][col] = B[row].toCharArray()[col];
}
}
for (int row = 0; row < map.length; row++) {
for (int col = 0; col < map[0].length; col++) {
if (map[row][col] == '#') { //there is a ship
map[row][col] = '.'; //assign . to make it visited
int count = getSizeOfShip(map, row, col); // standard BFS logic
if (count <= 3)
result[count - 1]++; //since we have 3 different of shapes, we can put each ship in their index size-1 to index0, size-2 to index1, size-3 to index2
}
}
}
return result;
}
public static int getSizeOfShip(char[][] map, int row, int col) {
int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[]{row, col});
int count = 1;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
int[] position = queue.remove();
for (int[] dir : dirs) {
int x = dir[0] + position[0];
int y = dir[1] + position[1];
if (x >= 0 && x < map.length && y >= 0 && y < map[0].length && map[x][y] == '#') {
map[x][y] = '.';
count++;
queue.add(new int[]{x, y});
}
}
}
}
return count;
}