문제 설명
게임 캐릭터를 4가지 명령어를 통해 움직이려 합니다. 명령어는 다음과 같습니다.
- U: 위쪽으로 한 칸 가기
- D: 아래쪽으로 한 칸 가기
- R: 오른쪽으로 한 칸 가기
- L: 왼쪽으로 한 칸 가기
캐릭터는 좌표평면의 (0, 0) 위치에서 시작합니다. 좌표평면의 경계는 왼쪽 위(-5, 5), 왼쪽 아래(-5, -5), 오른쪽 위(5, 5), 오른쪽 아래(5, -5)로 이루어져 있습니다.
예를 들어, "ULURRDLLU"로 명령했다면
- 1번 명령어부터 7번 명령어까지 다음과 같이 움직입니다.
- 8번 명령어부터 9번 명령어까지 다음과 같이 움직입니다.
이때, 우리는 게임 캐릭터가 지나간 길 중 캐릭터가 처음 걸어본 길의 길이를 구하려고 합니다. 예를 들어 위의 예시에서 게임 캐릭터가 움직인 길이는 9이지만, 캐릭터가 처음 걸어본 길의 길이는 7이 됩니다. (8, 9번 명령어에서 움직인 길은 2, 3번 명령어에서 이미 거쳐 간 길입니다)
단, 좌표평면의 경계를 넘어가는 명령어는 무시합니다.
예를 들어, "LULLLLLLU"로 명령했다면
- 1번 명령어부터 6번 명령어대로 움직인 후, 7, 8번 명령어는 무시합니다. 다시 9번 명령어대로 움직입니다.
이때 캐릭터가 처음 걸어본 길의 길이는 7이 됩니다.
명령어가 매개변수 dirs로 주어질 때, 게임 캐릭터가 처음 걸어본 길의 길이를 구하여 return 하는 solution 함수를 완성해 주세요.
제한사항
- dirs는 string형으로 주어지며, 'U', 'D', 'R', 'L' 이외에 문자는 주어지지 않습니다.
- dirs의 길이는 500 이하의 자연수입니다.
입출력 예
dirs | answer |
"ULURRDLLU" | 7 |
"LULLLLLLU" | 7 |
실패한 풀이
function solution(dirs) {
let answer = 0,coordinate=[],now=[0,0]
dirs.split('').forEach(v=>{
let before=[now[0],now[1]]
if(now[1]!==5&&v=='U') now[1]++
else if(now[1]!==-5&&v=='D') now[1]--
else if(now[0]!==-5&&v=='L') now[0]--
else if(now[0]!==5&&v=='R') now[0]++
if((before[0]!==now[0]||before[1]!==now[1])&&
coordinate.includes(`${before[0]},${before[1]},${now[0]},${now[1]}`)==false
){
coordinate.push(`${before[0]},${before[1]},${now[0]},${now[1]}`)
answer++
}
})
return answer
}
테스트 케이스 7번까지만 통과하고 8번부터 전부 실패가 나왔다.
뭘 틀렸나 해서 질문하기 를 보니 왼쪽에서 오른쪽으로 간 경로랑 오른쪽에서 왼쪽으로 간 경로는 같은 경로라는 어떤 분의 글을 보고
아차 싶어서 조건을 추가했다.
성공한 풀이
function solution(dirs) {
let answer = 0,coordinate=[],now=[0,0]
//coordinate :방문한 좌표를 담는 배열, now :현재 위치를 담는 배열
dirs.split('').forEach(v=>{
let before=[now[0],now[1]]
if(now[1]!==5&&v=='U') now[1]++
else if(now[1]!==-5&&v=='D') now[1]--
else if(now[0]!==-5&&v=='L') now[0]--
else if(now[0]!==5&&v=='R') now[0]++
if((before[0]!==now[0]||before[1]!==now[1])&&
coordinate.includes(`${before[0]},${before[1]},${now[0]},${now[1]}`)==false&&
coordinate.includes(`${now[0]},${now[1]},${before[0]},${before[1]}`)==false
){ //여기서 마지막 조건 추가
coordinate.push(`${before[0]},${before[1]},${now[0]},${now[1]}`)
answer++
}
})
return answer
}
풀이 전략
1. dirs 를 순회하며 이동하기 전 좌표를 before에 담고 각 명령어에 따라 이동한 후의 위치는 now가 된다.
(&&연산자로 좌표의 제한을 둠)
2. before와 now가 x,y좌표 둘다 같지 않으면서(하나라도 달라야 함) coordinate배열에 before-now(now-before도 같은 경로이므로 조건에 추가) 로 가는 경로가 포함되어 있지 않으면 새로운 경로이므로 coordinate배열에 집어넣고 answer++
** 여기서 백틱으로 감싸서 확인하고 넣는 이유는?
.includes() 메서드는 배열 안에 원하는 값이 있는지를 확인할 때 boolean을 반환한다.
배열 안에 배열이 있는지는 확인하지 못하기 때문에 .includes() 메서드를 사용하려면 문자열 형태로 넣어주어야 한다.
문자열 사이에 변수를 넣고 싶기 때문에 백틱을 사용하였다.