on&on
[Algorithm] 프로그래머스 - 캐릭터의 좌표🤖 본문
문제 설명
머쓱이는 RPG게임을 하고 있습니다. 게임에는 up, down, left, right 방향키가 있으며 각 키를 누르면 위, 아래, 왼쪽, 오른쪽으로 한 칸씩 이동합니다. 예를 들어 [0,0]에서 up을 누른다면 캐릭터의 좌표는 [0, 1], down을 누른다면 [0, -1], left를 누른다면 [-1, 0], right를 누른다면 [1, 0]입니다. 머쓱이가 입력한 방향키의 배열 keyinput와 맵의 크기 board이 매개변수로 주어집니다. 캐릭터는 항상 [0,0]에서 시작할 때 키 입력이 모두 끝난 뒤에 캐릭터의 좌표 [x, y]를 return하도록 solution 함수를 완성해주세요.
• [0, 0]은 board의 정 중앙에 위치합니다. 예를 들어 board의 가로 크기가 9라면 캐릭터는 왼쪽으로 최대 [-4, 0]까지 오른쪽으로 최대 [4, 0]까지 이동할 수 있습니다.
제한사항
• board은 [가로 크기, 세로 크기] 형태로 주어집니다.
• board의 가로 크기와 세로 크기는 홀수입니다.
• board의 크기를 벗어난 방향키 입력은 무시합니다.
• 0 ≤ keyinput의 길이 ≤ 50
• 1 ≤ board[0] ≤ 99
• 1 ≤ board[1] ≤ 99
• keyinput은 항상 up, down, left, right만 주어집니다.
입출력 예
keyinput | board | result |
["left", "right", "up", "right", "right"] | [11, 11] | [2, 1] |
["down", "down", "down", "down", "down"] | [7, 9] | [0, -4] |
풀이
function solution(keyinput, board) {
let x = 0 ,y = 0
const wall = [ Math.floor(board[0]/2), Math.floor(board[1]/2) ]
keyinput.map(i => {
switch(i){
case "left" : x--; break;
case "right" : x++; break;
case "down" : y--; break;
case "up" : y++; break;
}
x=Math.abs(x)<wall[0] ? x : x>0 ? wall[0] : wall[0]*-1
y=Math.abs(y)<wall[1] ? y : y>0 ? wall[1] : wall[1]*-1
})
return [x,y]
}
코드 설명
아래의 값을 실행했을 경우를 토대로 설명
console.log(solution(["down", "down", "down", "down", "down"], [7, 9]))
1️⃣
let x = 0 ,y = 0
const wall = [ Math.floor(board[0]/2), Math.floor(board[1]/2) ]
board는 [7, 9]로 설정되었기 때문에 아래 그림처럼 영점은 (4, 5)로 설정된다.
그렇기 때문에 위 아래로 움직일 수 있는 거리는 각 값을 2로 나누고 소수점을 제외한 값이 된다.
영점을 제외해야 하기 때문에 Math.ceil이 아닌 Math.floor을 사용한다.
x축으로 이동할 수 있는 거리는 ±2, y축으로 이동할 수 있는 거리는 ±4
2️⃣
keyinput.map(i => {
switch(i){
case "left" : x--; break;
case "right" : x++; break;
case "down" : y--; break;
case "up" : y++; break;
}
x=Math.abs(x)<wall[0] ? x : x>0 ? wall[0] : wall[0]*-1
y=Math.abs(y)<wall[1] ? y : y>0 ? wall[1] : wall[1]*-1
})
keyinput으로 들어온 ["down", "down", "down", "down", "down"] 값을 순회하면서 switch문으로
left일 때는 x - 1, right일 때는 x + 1, down일 때는 y - 1, up일 때는 y + 1을 하면서 x, y값을 설정한다.
이 때 board의 크기를 넘어갈 수 없기 때문에 x 또는 y의 절댓값이 위에서 설정한 wall보다 커질 경우 각각 값을 wall로 설정한다.
만약 x 또는 y가 0보다 작을 경우 wall에 -1을 곱해서 적절한 값을 설정하면 된다.
3️⃣
return [x, y]
마지막으로 x, y를 배열 형태로 반환해주면 해결!
테스트에서 계속 실패한다면, 이러한 테스트 케이스를 추가해서 해보는 것을 추천한다.
keyinput | board | result |
["left", "left", "left", "right"] | [3, 3] | [0, 0] |
[-1, 0]가 반환된다면... 다시 생각해보기...
나도 제출 후 채점에서 실패해서 반례를 찾아봤다....
코드 위치 하나 수정하니까 바로 해결됐다는.... 😂
다른 사람의 풀이
function solution(keyinput, board) {
let res = [0,0];
for (let p of keyinput) {
switch(p){
case 'left': if (-res[0] < board[0]/2-1) res[0]--; break;
case 'right': if (res[0] < board[0]/2-1) res[0]++; break;
case 'up': if (res[1] < board[1]/2-1) res[1]++; break;
case 'down': if (-res[1] < board[1]/2-1) res[1]--; break;
}
}
return res;
}
const CONTROL = {
up: [0, 1],
down: [0, -1],
left: [-1, 0],
right: [1, 0],
}
function solution(key, [n, m]) {
const [x1, x2] = [-(n-1)/2, (n-1)/2];
const [y1, y2] = [-(m-1)/2, (m-1)/2];
return key.reduce(([x, y], k) => {
const [nx, ny] = [x + CONTROL[k][0], y + CONTROL[k][1]];
if (x1 <= nx && nx <= x2 && y1 <= ny && ny <= y2) return [nx, ny];
return [x, y];
}, [0, 0]);
}
참고해서 호로록 풀어보잣!
'Algorithm' 카테고리의 다른 글
[Algorithm] 프로그래머스 - 평행🤖 (0) | 2022.12.08 |
---|