본문 바로가기
🍪 Ect/#Study

[99클럽 코테 스터디] 27일차 TIL 시뮬레이션

by 개발한 너굴씨 2024. 8. 17.
728x90

 

 

오늘의 문제는 프로그래머스

 

공원 산책

 

 

문제

 

 

문제 설명 

로봇 강아지는 현재 위치 S에서 수행할 명령 routes에 따라 공원을 이동해야 합니다. routes는 "op n" 원소로 이루어지는데 여기서 op란 동, 서, 남, 북 네 방향 중 이동할 방향을 의미하고 n은 이동할 칸 수를 의미합니다. 

공원은 좌측 상단 (0,0) 부터 우측 하단 (H - 1, W - 1) 크기의 직사각형입니다. 공원이 시작 지점 S, 이동 가능한 통로 O, 장애물 X로 이루어진 배열일 때 다음과 같은 예외 조건이 있습니다. 

1. 주어진 방향으로 이동할 때 공원을 벗어나는지 확인합니다. 

2. 주어진 방향으로 이동 중 장애물을 만나는지 확인합니다. 

위 두 가지 중 하나라도 해당된다면 해당 명령을 무시하고 다음 명령을 수행해야 합니다. 

최종적으로 모든 명령을 수행 한 뒤의 위치를 [세로 방향 좌표, 가로 방향 좌표] 순으로 배열에 담아 반환하면 되는 문제입니다. 

 

 

 

 

문제 풀이 시간 

권장 풀이 시간은 60분이었고, 저는 55분이 걸렸습니다.

 

 

 

문제 접근 방식

문제에서 요구하는 것은 로봇 강아지가 주어진 경로를 따라 공원을 이동한 다음의 최종 위치를 반환하는 것입니다. 먼저 공원 내에서 로봇 강아지의 시작 위치를 찾습니다. 각 명령에 따라 로봇 강아지가 이동할 때 이동할 방향과 칸 수를 확인합니다. 이동 중 공원을 벗어나거나 또는 장애물을 만난 경우 해당 명령을 무시하는 예외 처리를 추가합니다. 마지막으로 모든 명령을 처리한 후 최종 위치를 반환합니다. 

 

 

 

문제 풀이

class Solution {
    public int[] solution(String[] park, String[] routes) {
        
        // 공원
        int h = park.length;
        int w = park[0].length(); 

        // 시작 위치 S
        int x = 0; 
        int y = 0;  

        // 북 남 서 동
        int dy[] = {-1,1,0,0};  
        int dx[] = {0,0,-1,1};  

        // 시작 위치 구하기 
        for(int i = 0; i < h; i ++) {
            for(int j = 0; j < w; j++) {
                if(park[i].charAt(j) == 'S') {
                    y = i;
                    x = j; 
                    break; // 전부 탐색할 필요 없음
                }
            }
        }

        // 주어진 경로 탐색하기 
        for(String route : routes) {
            
            char moveType = route.charAt(0);    // 방향
            int move = route.charAt(2) - '0';   // 이동 거리 

            boolean block = false; // 장애물 여부 
            int direction = 0; 

            switch(moveType) {
                case 'N' : 
                    direction = 0;
                    break; 
                case 'S' :
                    direction = 1;
                    break;
                case 'W' : 
                    direction = 2;
                    break;
                case 'E' :
                    direction = 3;
                    break;  
            }

            // 로봇 강아지 위치 
            int ny = y;  
            int nx = x;  

            // 공원을 벗어나거나 장애물을 만났을 경우 block은 true 
            for(int i = 0; i < move; i++) {
                
                ny += dy[direction];
                nx += dx[direction];

                if(ny < 0 || ny >= h || nx < 0 || nx >= w || park[ny].charAt(nx) == 'X') {
                    block = true; 
                    break; 
                }
            }

            // 이동 중 경계를 벗어나거나 장애물을 만나지 않았을 때만 최종 위치를 업데이트
            if(!block) {
                y = ny;
                x = nx; 
            }

        }
        
        int[] answer = {y, x}; 
        return answer;
    }
}

 

 

방향 저장 및 처리하기 

문제에서 로봇 강아지는 북, 남, 서, 동 네 방향으로 이동할 수 있습니다. 이를 아래와 같이 배열에 저장해 처리하였습니다. 

int dy[] = {-1, 1, 0, 0};
int dx[] = {0, 0, -1, 1};

 

  • 북 : dy[0] = -1, dx[0] = 0 
  • 남 : dy[1] = 1, dx[1] = 0
  • 서 : dy[2] = 0, dx[2] = -1
  • 동 : dy[3] = 0, dx[3] = 1

 

 

예외 처리 

이동 중 공원을 벗어나거나 장애물을 만난 경우, 해당 이동을 무시하고 다음 명령으로 넘어가야 합니다. 

 

공원을 벗어나는 경우

새로운 위치가 공원 범위를 벗어나는지 확인합니다. y가 음수이거나 혹은 공원의 세로 길이 보다 큰 경우, 그리고 x가 음수이거나 공원의 가로 길이 보다 큰 경우에 공원을 벗어난 것으로 간주하고 다음 명령으로 이동합니다. 

 

장애물을 만난 경우 

이동 경로에 장애물 X가 있는지 확인합니다. 만약 장애물을 만나면 다음 명령으로 이동합니다. 

 

 

 

코드 개선하기

1. outerLoop 레이블을 이용해 시작 위치를 찾았을 때 이중 루프를 완전히 빠져나오도록 수정합니다. 

2. switch문을 제거하고 문자열 directions에서 indexOf를 사용해 방향을 매핑합니다. 

3. block 변수를 제거하고 장애물이 있거나 범위를 벗어났을 경우 이전 위치로 복귀 하도록 합니다. 

class Solution {
    public int[] solution(String[] park, String[] routes) {
        
        // 공원 크기
        int h = park.length;
        int w = park[0].length(); 

        // 시작 위치 S 찾기
        int y = 0, x = 0;
        outerLoop:
        for(int i = 0; i < h; i++) {
            for(int j = 0; j < w; j++) {
                if(park[i].charAt(j) == 'S') {
                    y = i;
                    x = j; 
                    break outerLoop; // 두 루프를 모두 탈출
                }
            }
        }

        // 북 남 서 동
        int[] dy = {-1, 1, 0, 0};  
        int[] dx = {0, 0, -1, 1};  
        String directions = "NSWE";

        // 주어진 경로 탐색하기 
        for(String route : routes) {
            int direction = directions.indexOf(route.charAt(0));  // 방향 인덱스
            int move = route.charAt(2) - '0';   // 이동 거리 

            // 새로운 위치 계산
            int ny = y, nx = x;
            for(int i = 0; i < move; i++) {
                ny += dy[direction];
                nx += dx[direction];
                
                // 공원을 벗어나거나 장애물에 부딪히는 경우 중지
                if(ny < 0 || ny >= h || nx < 0 || nx >= w || park[ny].charAt(nx) == 'X') {
                    ny = y; // 원래 위치로 복귀
                    nx = x;
                    break;
                }
            }

            // 최종 위치 업데이트
            y = ny;
            x = nx;
        }
        
        return new int[]{y, x};
    }
}

 

 

 

 

 

이렇게 오늘 27일차 TIL을 작성해 보았습니다.

 

 

 

 

728x90

댓글