[프로그래머스 Lev.2] 리코쳇 로봇

정진수·2024년 4월 29일
0

[문제풀이]

시작 위치인 R 위치에서 목적 위치인 G로만 가면 되는 문제인줄 알았다. 하지만 예시를 보니 그런 문제가 아니었다... 다시 문제를 읽어보니 문제가 이해가 되지 않았다. 이래서 책을 많이 읽으라고 하는 것 같다... 다시 집중해서 읽어보니 목적지 위치를 거치면 로직이 끝나는 것이 아니고 로봇이 멈춘 위치가 목적지 위치여야 하는 것이었다. 멈추는 조건은 벽에 부딪히거나 즉 배열 범위를 벗어나거나 장애물 위치인 D 위치에 도달하면 멈추고 방향을 바꿔 또 다시 벽이나 장애물 위치에 도달하면 멈추고 방향을 바꾸는 방식이다. 이와 같은 조건을 제외하곤 일반 경로 탐색과 유사하다.

[코드]

import java.util.*;

class Solution {
    static class Robot{
        int x, y, cnt;
        Robot(int x, int y, int cnt){
            this.x = x;
            this.y = y;
            this.cnt = cnt;
        }
    }
    static int[] dx = {-1, 1, 0, 0};
    static int[] dy = {0, 0, -1, 1};
    static int startX, startY;
    static int endX, endY;
    static char[][] map;
    static boolean[][] visited;
    static int cnt;

    static public int solution(String[] board) {
        int answer = -1;

        int row = board.length;
        int height = board[0].length();

        Queue<Robot> q = new ArrayDeque<>();
        visited = new boolean[row][height];
        map = new char[row][height];

	    // 1차원 String 배열을 char[][] 배열로 변환하고 시작 위치와 목적 위치 좌표 값 저장
        for(int i=0; i<board.length; i++){
            for(int j=0; j<board[i].length(); j++){
                map[i][j] = board[i].charAt(j);
                if(board[i].substring(j, j+1).equals("R")){
                    startX = i;
                    startY = j;
                }
                if(board[i].substring(j, j+1).equals("G")){
                    endX = i;
                    endY = j;
                }
            }
        }

        q.add(new Robot(startX, startY, 0));

        while(!q.isEmpty()) {
            Robot cur = q.poll();

            int x = cur.x;
            int y = cur.y;
            int cnt = cur.cnt;

            visited[x][y] = true;

            if(x == endX && y == endY) {
                return cnt;
            }

            for(int k=0; k<4; k++){
                int nx = x + dx[k];
                int ny = y + dy[k];
				
                // 벽이나 장애물 위치가 나올 때까지 해당 방향으로 전진
                while (nx>=0 && ny >= 0 && nx < row && ny < height && map[nx][ny] != 'D'){
                    nx += dx[k];
                    ny += dy[k];
                }

                nx -= dx[k];
                ny -= dy[k];

				// 방문했던 위치거나 바로 장애물이나 벽이 나오는 위치 일 때 
                if(visited[nx][ny] || (x == nx && y == ny)) continue;
                visited[nx][ny] = true;
                q.add(new Robot(nx, ny, cnt+1));
            }

        }

        return answer;
    }
}

[고려했던 점]

while (nx>=0 && ny >= 0 && nx < row && ny < height && map[nx][ny] != 'D') 코드를 처음에 while(map[nx][ny] == 'D' || nx<0 || ny < 0 || nx> row || ny > height)로 작성했을 때 map[nx][ny] == 'D' 부분을 먼저 적는 것이 아닌 범위를 벗어나는지 여부부터 판별하지 않으면 범위를 벗어난 배열 값을 찾아 ArrayIndexOut 에러가 발생한다. 코드의 순서에 따라 로직이 완전히 바뀐다는 것을 항상 인지하며 코드를 작성해야겠다.....

profile
소통능력을 겸비한 자바 백엔드 개발자

0개의 댓글