«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Recent Posts
Today
Total
관리 메뉴

on&on

[Algorithm] 프로그래머스 - 캐릭터의 좌표🤖 본문

Algorithm

[Algorithm] 프로그래머스 - 캐릭터의 좌표🤖

다느 2022. 12. 1. 22:55

프로그래머스 캐릭터의 좌표

 

문제 설명

머쓱이는 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
Comments