diff --git a/src/Search.java b/src/Search.java index cebb278..8b151c7 100644 --- a/src/Search.java +++ b/src/Search.java @@ -1,34 +1,80 @@ +import java.util.*; + public class Search { - /** - * Finds the location of the nearest reachable cheese from the rat's position. - * Returns a 2-element int array: [row, col] of the closest 'c'. If there are multiple - * cheeses that are tied for the same shortest distance to reach, return - * any one of them. - * - * 'R' - the rat's starting position (exactly one) - * 'o' - open space the rat can walk on - * 'w' - wall the rat cannot pass through - * 'c' - cheese that the rat wants to reach - * - * If no rat is found, throws EscapedRatException. - * If more than one rat is found, throws CrowdedMazeException. - * If no cheese is reachable, throws HungryRatException - * - * oooocwco - * woowwcwo - * ooooRwoo - * oowwwooo - * oooocooo - * - * The method will return [0,4] as the nearest cheese. - * - * @param maze 2D char array representing the maze - * @return int[] location of the closest cheese in row, column format - * @throws EscapedRatException if there is no rat in the maze - * @throws CrowdedMazeException if there is more than one rat in the maze - * @throws HungryRatException if there is no reachable cheese - */ - public static int[] nearestCheese(char[][] maze) throws EscapedRatException, CrowdedMazeException, HungryRatException { - return null; + public static int[] nearestCheese(char[][] maze) + throws EscapedRatException, CrowdedMazeException, HungryRatException { + int[] start = findRat(maze); + + Queue queue = new LinkedList<>(); + queue.add(start); + + boolean[][] visited = new boolean[maze.length][maze[0].length]; + + while (!queue.isEmpty()) { + int[] current = queue.poll(); + int curR = current[0], curC = current[1]; + + // If this is cheese, we’re done + if (maze[curR][curC] == 'c') { + return current; + } + + if (visited[curR][curC]) { + continue; + } + visited[curR][curC] = true; + + // Add all valid neighbor moves + for (int[] next : possibleMoves(maze, current)) { + if (!visited[next[0]][next[1]]) { + queue.add(next); + } + } + } + + // No reachable cheese + throw new HungryRatException(); } -} \ No newline at end of file + + public static List possibleMoves(char[][] maze, int[] loc) { + List moves = new ArrayList<>(); + int r = loc[0], c = loc[1]; + + int[][] dirs = { + {1, 0}, {-1, 0}, {0, 1}, {0, -1} + }; + + for (int[] d : dirs) { + int nr = r + d[0], nc = c + d[1]; + if (nr >= 0 && nr < maze.length && + nc >= 0 && nc < maze[0].length && + maze[nr][nc] != 'w') { + moves.add(new int[]{nr, nc}); + } + } + return moves; + } + + public static int[] findRat(char[][] maze) + throws EscapedRatException, CrowdedMazeException { + int count = 0; + int[] loc = null; + + for (int r = 0; r < maze.length; r++) { + for (int c = 0; c < maze[0].length; c++) { + if (maze[r][c] == 'R') { + count++; + loc = new int[]{r, c}; + } + } + } + + if (count == 0) { + throw new EscapedRatException(); + } + if (count > 1) { + throw new CrowdedMazeException(); + } + return loc; + } +}