문제설명
지나다니는 길을 'O', 장애물을 'X'로 나타낸 직사각형 격자 모양의 공원에서 로봇 강아지가 산책을 하려합니다. 산책은 로봇 강아지에 미리 입력된 명령에 따라 진행하며, 명령은 다음과 같은 형식으로 주어집니다.
["방향 거리", "방향 거리" … ]
예를 들어 "E 5"는 로봇 강아지가 현재 위치에서 동쪽으로 5칸 이동했다는 의미입니다. 로봇 강아지는 명령을 수행하기 전에 다음 두 가지를 먼저 확인합니다.
- 주어진 방향으로 이동할 때 공원을 벗어나는지 확인합니다.
- 주어진 방향으로 이동 중 장애물을 만나는지 확인합니다.
위 두 가지중 어느 하나라도 해당된다면, 로봇 강아지는 해당 명령을 무시하고 다음 명령을 수행합니다.
공원의 가로 길이가 W, 세로 길이가 H라고 할 때, 공원의 좌측 상단의 좌표는 (0, 0), 우측 하단의 좌표는 (H - 1, W - 1) 입니다.
공원을 나타내는 문자열 배열 park, 로봇 강아지가 수행할 명령이 담긴 문자열 배열 routes가 매개변수로 주어질 때, 로봇 강아지가 모든 명령을 수행 후 놓인 위치를 [세로 방향 좌표, 가로 방향 좌표] 순으로 배열에 담아 return 하도록 solution 함수를 완성해주세요.
park | routes | result |
---|---|---|
["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! 까지는 좋았으나 너무 결과만 생각했던 것 같다. 어떤 과정을 거쳐야하는지에 대해 생각하고, 주어진 값을 통해 내가 어떻게 사용할 수 있는지도 유의깊게 보는 연습을 해야겠다.