프로그래머스 1단계 - 공원산책 본문
1 단계 : 공원산책
코딩테스트 연습 > 연습문제 > 공원산책
문제 설명
지나다니는 길을 '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는 다음 네 가지중 하나로 이루어져 있습니다.
입출력 예
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] |
입출력 예 설명
입출력 예 #1
입력된 명령대로 동쪽으로 2칸, 남쪽으로 2칸, 서쪽으로 1칸 이동하면 [0,0] -> [0,2] -> [2,2] -> [2,1]이 됩니다.
입출력 예 #2
입력된 명령대로라면 동쪽으로 2칸, 남쪽으로 2칸, 서쪽으로 1칸 이동해야하지만 남쪽으로 2칸 이동할 때 장애물이 있는 칸을 지나기 때문에 해당 명령을 제외한 명령들만 따릅니다. 결과적으로는 [0,0] -> [0,2] -> [0,1]이 됩니다.
입출력 예 #3
처음 입력된 명령은 공원을 나가게 되고 두 번째로 입력된 명령 또한 장애물을 지나가게 되므로 두 입력은 제외한 세 번째 명령만 따르므로 결과는 다음과 같습니다. [0,1] -> [0,0]
코드
function solution(park, routes) {
// 가로와 세로값은 각각 길이 - 1 값, 가로3, 세로4 면 세로로 0,1,2,3 // 가로로 0,1,2 이렇게 인덱스 접근이 되겠죠?
const hLimit = park.length - 1;
const wLimit = park[0].length - 1;
// 핵심로직인 최종 return 할 배열, 0,0 으로 초기화
let s = [0, 0];
// 그런데 시작이 꼭 0,0이 아니기 때문에, S의 좌표를 찾아주는 작업을 한다.
for (let i = 0; i < park.length; i++) {
for (let j = 0; j < park[0].length; j++) {
if (park[i][j] === "S") {
s[0] = i;
s[1] = j;
}
}
}
// 움직이기
for (let i = 0; i < routes.length; i++) {
const dir = routes[i].split(" ")[0];
const amount = Number(routes[i].split(" ")[1]);
let flag = true;
switch (dir) {
// N일경우 위쪽으로 움직인다
// 음수가 되면 안되겠죠? 3, 2, 1, 0 까지만 움직일 수 있잖아요? 아니면 공원을 벗어나는거고
// 또한 움직일 경로에 X가 있으면 안되겠죠? 현재위치 - 1 부터 amount 만큼 움직여보면서 X를 찾습니다.
// 밑에도 이런식으로 생각해서 작성해줍니다.
case "N":
if (s[0] - amount >= 0) {
for (let h = s[0] - 1; h >= s[0] - amount; h--) {
if (park[h][s[1]] === "X") {
flag = false;
break;
}
}
if (flag) s[0] -= amount;
}
break;
case "S":
if (s[0] + amount <= hLimit) {
for (let h = s[0] + 1; h <= s[0] + amount; h++) {
if (park[h][s[1]] === "X") {
flag = false;
break;
}
}
if (flag) s[0] += amount;
}
break;
case "E":
if (s[1] + amount <= wLimit) {
for (let w = s[1] + 1; w <= s[1] + amount; w++) {
if (park[s[0]][w] === "X") {
flag = false;
break;
}
}
if (flag) s[1] += amount;
}
break;
case "W":
if (s[1] - amount >= 0) {
for (let w = s[1] - 1; w >= s[1] - amount; w--) {
if (park[s[0]][w] === "X") {
flag = false;
break;
}
}
if (flag) s[1] -= amount;
}
break;
default:
break;
}
}
return s;
}
리뷰
1. 로봇강아지가 해당 명령을 무시할 조건을 찾기위해 hLimit과 wLimit을 찾아줍니다.
2. 시작점 s를 찾아줍니다. 항상 0,0 이 아니기 때문이죠
3. 이제 움직이는데 routes배열을 돌면서 방향과 총량만큼 움직여줍니다. 그런데 조건을 따져봐야겠죠?
4. S, E 는 각각 hLimit, wLimit을 초과하지 않는 범위 내에서 움직여야 합니다. N, W는 값이 음수로 이동하면 안되구요
5. 해당 조건을 통과하면 구한 시작점에서 이동을 시켜줍니다. S,N이면 s[0], W,E이면 s[1]을 움직여주면 되겠죠?
총평 : 차근차근 생각하면서 문제의 순서대로 풀면 특별히 다른요소를 생각할 필요는 없는 것 같습니다. 로봇강아지가 해당 명령을 무시하는 조건만 잘 체크해준다면요!
'알고리즘 > 1단계' 카테고리의 다른 글
프로그래머스 1단계 - 달리기 경주 (0) | 2023.04.08 |
---|---|
프로그래머스 1단계 - 추억 점수 (4) | 2023.04.01 |
프로그래머스 1단계 - 덧칠하기 (0) | 2023.03.25 |
프로그래머스 1단계 - 바탕화면 정리 (0) | 2023.03.04 |
프로그래머스 1단계 - 대충 만든 자판 (2) | 2023.02.27 |