문제
https://school.programmers.co.kr/learn/courses/30/lessons/172928
문제 설명
지나다니는 길을 'O', 장애물을 'X'로 나타낸 직사각형 격자 모양의 공원에서 로봇 강아지가 산책을 하려합니다. 산책은 로봇 강아지에 미리 입력된 명령에 따라 진행하며, 명령은 다음과 같은 형식으로 주어집니다.
- ["방향 거리", "방향 거리" … ]
예를 들어 "E 5"는 로봇 강아지가 현재 위치에서 동쪽으로 5칸 이동했다는 의미입니다. 로봇 강아지는 명령을 수행하기 전에 다음 두 가지를 먼저 확인합니다.
- 주어진 방향으로 이동할 때 공원을 벗어나는지 확인합니다.
- 주어진 방향으로 이동 중 장애물을 만나는지 확인합니다.
위 두 가지중 어느 하나라도 해당된다면, 로봇 강아지는 해당 명령을 무시하고 다음 명령을 수행합니다.
공원의 가로 길이가 W, 세로 길이가 H라고 할 때, 공원의 좌측 상단의 좌표는 (0, 0), 우측 하단의 좌표는 (H - 1, W - 1) 입니다.
공원을 나타내는 문자열 배열 park, 로봇 강아지가 수행할 명령이 담긴 문자열 배열 routes가 매개변수로 주어질 때, 로봇 강아지가 모든 명령을 수행 후 놓인 위치를 [세로 방향 좌표, 가로 방향 좌표] 순으로 배열에 담아 return 하도록 solution 함수를 완성해주세요.
제한사항
- 3 ≤ park의 길이 ≤ 50
- 3 ≤ park[i]의 길이 ≤ 50
- park[i]는 다음 문자들로 이루어져 있으며 시작지점은 하나만 주어집니다.
- S : 시작 지점
- O : 이동 가능한 통로
- X : 장애물
- park[i]는 다음 문자들로 이루어져 있으며 시작지점은 하나만 주어집니다.
- park는 직사각형 모양입니다.
- 3 ≤ park[i]의 길이 ≤ 50
- 1 ≤ routes의 길이 ≤ 50
- routes의 각 원소는 로봇 강아지가 수행할 명령어를 나타냅니다.
- 로봇 강아지는 routes의 첫 번째 원소부터 순서대로 명령을 수행합니다.
- routes의 원소는 "op n"과 같은 구조로 이루어져 있으며, op는 이동할 방향, n은 이동할 칸의 수를 의미합니다.
- op는 다음 네 가지중 하나로 이루어져 있습니다.
- N : 북쪽으로 주어진 칸만큼 이동합니다.
- S : 남쪽으로 주어진 칸만큼 이동합니다.
- W : 서쪽으로 주어진 칸만큼 이동합니다.
- E : 동쪽으로 주어진 칸만큼 이동합니다.
- 1 ≤ n ≤ 9
- op는 다음 네 가지중 하나로 이루어져 있습니다.
풀이
1. 처음 시작하는 x좌표와 y좌표 값을 담기 위해 2중 for문을 작성했다.
xy[0][0]에 값을 넣기 위해서 배열 x 에 park[0~2] 을 char 배열 형태로 저장한다. 그 다음 xy[0][0]에 x[0] 즉 'S'를 넣어준다.
보통 우리가 좌표를 떠올리면 (x,y) 좌표를 생각하지만 이 문제에서는 (y, x) 형식으로 출력해야 한다는 것을 생각하여 startX = j, startY = i 를 저장했다.
2. routes 배열에 들어 있는 방향과 이동 거리 값을 각각의 배열에 저장하여 준다.
split(" ")[0] 을 사용하면 공백으로 분리한 다음 첫 번째 원소만 저장할 수 있다.
3. 배열 routes 의 길이 만큼 반복문을 돌며 switch를 이용해 방향에 따라 공원을 벗어나지 않는지 체크해 주고 벗어나지 않는다면 moveToX() / moveToY() 메서드를 실행하여 x좌표 또는 y좌표를 이동해 준다.
4. moveToX()와 moveToY() 안에서도 방향에 따라 조건을 다르게 해야 하기 때문에 moveToX는 "E"와 "W"인 경우로, moveToY는 "S"와 "N"인 경우로 나누어 놨다.
moveToX()의 "E"인 경우로 설명하면 만약 중간에 'X'를 만난다면 원래 값으로 돌아가야 하기 때문에 변수 X에 startX값을 저장한다. for문이 시작하자 마자 startX에 1을 더해주어 다음 칸으로 이동하게 한다. 그리고 계속 한 칸씩 이동하면서 배열 xy에 'X'가 있는지 확인하며 있다면 1씩 증가하던 startX를 처음에 받은 값으로 되돌리며 for문을 탈출한다.
5. 그렇게 계산한 startX와 startY 값을 int 배열인 answer에 받으면 되는데, 이 때, startY와 startX의 순서만 주의하면 된다.
class Solution {
public int[] solution(String[] park, String[] routes) {
int startX = 0;
int startY = 0;
int height = park.length;
int width = park[0].length();
// 1. 배열 park 2차원 배열로 변경하며 시작 좌표 찾기
char[][] xy = new char[height][width];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
char[] x = park[i].toCharArray();
xy[i][j] = x[j];
if (xy[i][j] == 'S') {
startX = j;
startY = i;
}
}
}
// 2. 배열 routes를 각각 방향과 거리를 담을 배열로 나누기
String[] direction = new String[routes.length];
int[] distance = new int[routes.length];
for (int i = 0; i < routes.length; i++) {
direction[i] = routes[i].split(" ")[0];
distance[i] = Integer.parseInt(routes[i].split(" ")[1]);
}
// 3. for분을 돌며 방향에 따라 조건이 맞는지 확인하고 맞다면 moveToX()/moveToY() 메서드 실행
for (int i = 0; i < routes.length; i++) {
switch (direction[i]) {
case "E":
if (startX + distance[i] < width) {
startX = moveToX(direction[i], startX, distance[i], xy, startY);
}
break;
case "W":
if (startX - distance[i] >= 0) {
startX = moveToX(direction[i], startX, distance[i], xy, startY);
}
break;
case "S":
if (startY + distance[i] < height) {
startY = moveToY(direction[i], startY, distance[i], xy, startX);
}
break;
case "N":
if (startY - distance[i] >= 0) {
startY = moveToY(direction[i], startY, distance[i], xy, startX);
}
break;
default:
break;
}
}
int[] answer = {startY, startX};
return answer;
}
// 4-1. x축 방향으로 움직여야 하는 방향 "E"와 "W"일 때 실행
public int moveToX(String direction, int startX, int d, char[][] xy, int startY) {
int X = startX;
if ("E".equals(direction)) {
for (int i = 0; i < d; i++) {
startX++;
if (xy[startY][startX] == 'X') {
startX = X;
break;
}
}
} else {
for (int i = 0; i < d; i++) {
startX--;
if (xy[startY][startX] == 'X') {
startX = X;
break;
}
}
}
return startX;
}
// 4-2. y축 방향으로 움직여야 하는 방향 "S"와 "N"일 때 실행
public int moveToY(String direction, int startY, int d, char[][] xy, int startX) {
int Y = startY;
if ("S".equals(direction)) {
for (int i = 0; i < d; i++) {
startY++;
if (xy[startY][startX] == 'X') {
startY = Y;
break;
}
}
} else {
for (int i = 0; i < d; i++) {
startY--;
if (xy[startY][startX] == 'X') {
startY = Y;
break;
}
}
}
return startY;
}
}
'Programmers > Lv.1' 카테고리의 다른 글
[프로그래머스][Lv.1][Java] 예산 (0) | 2023.08.11 |
---|---|
[프로그래머스][Lv.1][Java][Queue] 카드 뭉치 (0) | 2023.08.10 |
[프로그래머스][Lv.1][Java][Stack] 크레인 인형뽑기 게임 (0) | 2023.08.09 |
[프로그래머스][Lv.1][Java] 문자열 나누기 (0) | 2023.08.08 |
[프로그래머스][Lv.1][Java][Hash] 대충 만든 자판 (0) | 2023.08.07 |