[프로그래머스/Java] - Lv1.공원산책

Eunjeon_g·2023년 6월 5일
0
post-thumbnail
post-custom-banner

문제설명

지나다니는 길을 'O', 장애물을 'X'로 나타낸 직사각형 격자 모양의 공원에서 로봇 강아지가 산책을 하려합니다. 산책은 로봇 강아지에 미리 입력된 명령에 따라 진행하며, 명령은 다음과 같은 형식으로 주어집니다.

["방향 거리", "방향 거리" … ]
예를 들어 "E 5"는 로봇 강아지가 현재 위치에서 동쪽으로 5칸 이동했다는 의미입니다. 로봇 강아지는 명령을 수행하기 전에 다음 두 가지를 먼저 확인합니다.

  • 주어진 방향으로 이동할 때 공원을 벗어나는지 확인합니다.
  • 주어진 방향으로 이동 중 장애물을 만나는지 확인합니다.

    위 두 가지중 어느 하나라도 해당된다면, 로봇 강아지는 해당 명령을 무시하고 다음 명령을 수행합니다.
    공원의 가로 길이가 W, 세로 길이가 H라고 할 때, 공원의 좌측 상단의 좌표는 (0, 0), 우측 하단의 좌표는 (H - 1, W - 1) 입니다.

    공원을 나타내는 문자열 배열 park, 로봇 강아지가 수행할 명령이 담긴 문자열 배열 routes가 매개변수로 주어질 때, 로봇 강아지가 모든 명령을 수행 후 놓인 위치를 [세로 방향 좌표, 가로 방향 좌표] 순으로 배열에 담아 return 하도록 solution 함수를 완성해주세요.
parkroutesresult
["SOO","OOO","OOO"]["E 2","S 2","W 1"][2,1]
["SOO","OXX","OOO"]["E 2","S 2","W 1"][0,1]
["OSO","OOO","OXO","OOO"]["E 2","S 3","W 1"][0,0]

입출력 예 #2

입력된 명령대로라면 동쪽으로 2칸, 남쪽으로 2칸, 서쪽으로 1칸 이동해야하지만 남쪽으로 2칸 이동할 때 장애물이 있는 칸을 지나기 때문에 해당 명령을 제외한 명령들만 따릅니다. 결과적으로는 [0,0] -> [0,2] -> [0,1]이 됩니다.

🤔생각해보기

방향의 종류는 고정이므로 switch를 통해 구분해주고, 첫 위치(S)를 기준으로 좌표를 이동해주면 될 것 같다.

👩🏻‍💻코드 작성해보기

import java.util.*;
class Solution {
    public int[] solution(String[] park, String[] routes) {
        int[] answer = new int[2];
        int w = park[0].length();
        int h = park.length;
        
        for(int i=0; i<park.length; i++){
            int n = park[i].indexOf('S');
             if(n != -1){
                answer[0] = i;
                answer[1] = n;
                break;
            }
        } 
        
        for(int i=0; i<routes.length; i++){
            String route[] = routes[i].split(" ");
            int r = Integer.parseInt(route[1]);
            boolean rst = true;
             switch(route[0]){
                case "E": 
                    if(answer[1] + r < w){
                        for(int j=1; j<=r; j++){
                            if(park[answer[0]].charAt(answer[1]+j) == 'X'){
                                rst = false;
                                break;                                
                            }
                        }
                        if(rst)
                            answer[1] += r;                         
                     }
                    break;
                case "W": 
                     if(answer[1] - r >= 0){
                        for(int j=r; j>=1; j--){
                            if(park[answer[0]].charAt(answer[1]-j) == 'X'){
                                rst = false;
                                break;                                
                            }
                        }
                        if(rst)
                            answer[1] -= r;                         
                     }
                    break;
                case "S": 
                     if(answer[0] + r < h){
                        for(int j=1; j<=r; j++){
                            if(park[answer[0]+j].charAt(answer[1]) == 'X'){
                                rst = false;
                                break;
                            }
                        }
                        if(rst)
                            answer[0] += r;                         
                     }
                    break;
                case "N": 
                      if(answer[0] - r >= 0){
                        for(int j=r; j>=1; j--){
                            if(park[answer[0]-j].charAt(answer[1]) == 'X'){
                                rst = false;
                                break;
                            }
                        }
                        if(rst)
                            answer[0] -= r;                         
                     }
                    break;
                 default:
                     break;
            }
        }        
        return answer;
    }
}

💬설명해보기

첫 번째 반복문을 통해 시작 위치(S)를 찾아준다.
두 번째 반복문에는 좌표를 움직이는 코드가 들어간다.

우선 "방향 거리"로 구성된 문자열을 분리시켜주고(split), 거리는 많이 사용할 예정이라 변수 r에 따로 담아준다.

방향(route[0])은 E,W,S,N 4개로 고정되어 있으므로 switch문을 통해 구분해준다.
switch에 있는 if문은 움직일 거리가 직사각형의 크기보다 넘치는지 확인해주고, for문을 통해 좌표를 한 칸씩 움직여 해당 위치까지 가는동안 장애물이 있는지 확인해준다.
park[행][열]이라고 생각할 경우 E,W는 좌/우로 움직이기 때문에 행의 값은 고정이고, 열의 값만 움직여 장애물을 확인해준다. S,N의 경우 위/아래로 움직이기 때문에 행의 값이 변경되고, 열의 값이 같을 때 장애물이 있는지 확인해준다.

만약 장애물이 있다면 rst값을 false로 변경하고, rst의 최종 값이 true일때만 해당거리까지 장애물이 없었던 것 이므로 좌표를 이동시켜준다.

🎙️후기
해결하는데 예상보다 시간이 걸렸다. 아마 다음과 같은 실수들 때문인 것 같다.
처음에 배열을 만들어 park에서 X의 위치를 1로 표시해주려했다. 생각해보니 그럴필요가 없었다. park배열이 내가 만들려는 배열이었다... 이미 존재하는 배열을 굳이 만들려고 했던 것이다.
다음으로 case문을 통해 좌표를 이동할 때 이동 완료한 위치에 장애물이 있는가?만 체크해줬다. 이동하는 중간에도 장애물이 있는지 확인해줬어야 하는데 말이다.

조건이 정해져 있으니(E/W/S/N) switch! 까지는 좋았으나 너무 결과만 생각했던 것 같다. 어떤 과정을 거쳐야하는지에 대해 생각하고, 주어진 값을 통해 내가 어떻게 사용할 수 있는지도 유의깊게 보는 연습을 해야겠다.
post-custom-banner

0개의 댓글