캐릭터의 좌표

Haizel·2023년 4월 7일
0

🧬 알고리즘 풀이

목록 보기
2/53
post-thumbnail

문제 설명

머쓱이는 RPG게임을 하고 있습니다. 게임에는 updownleftright 방향키가 있으며 각 키를 누르면 위, 아래, 왼쪽, 오른쪽으로 한 칸씩 이동합니다. 예를 들어 [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]까지 이동할 수 있습니다.

입출력 예

keyinputboardresult
["left", "right", "up", "right", "right"][11, 11][2, 1]
["down", "down", "down", "down", "down"][7, 9][0, -4]

처음 풀이

function solution(keyinput, board) {
  let upDown = 0;
  let leftRight = 0;
  for (let el of keyinput) {
    console.log(el);
    if (el === "up" || el === "down") {
      el === "up" ? upDown++ : upDown--;
    } else if (el === "left" || el === "right") {
      el === "left" ? leftRight-- : leftRight++;
    }
  }
  if (Math.abs(leftRight) > Math.floor(board[0] / 2)) {
      leftRight = Math.floor(board[0] / 2);
      console.log(leftRight);
    } else if (Math.abs(upDown) > Math.round(board[1] / 2)) {
      upDown = Math.round(board[1] / 2);
    }
    return [leftRight, upDown];
}

💡 문제점
  • 이미 x축 혹은 y축의 끝에 있을 경우 → 이동할 수 없는 반례를 고려하지 않았다. 그 결과,
  1. 첫번째 테스트케이스만 통과되고, 두번째 테스트케이스는 통과되지 않는다.

  2. 추가한 테스트케이스(끝에서 → 끝으로 이동)도 통과되지 않았다.


두번째 풀이

function solution(keyinput, board) {
    //1. [0,0]에서 시작하므로
    let x = 0;
    let y = 0;
    
    //2. board에 크기도 정해져 있기때문에 마찬가지로, x/y가 갈 수 있는 범위를 지정한다.
    let xRange = (board[0] / 2);
    let yRange = (board[1] / 2);
    
    //3. keyinput을 순회하며 right라면 x+1, left는 x-1, up은 y+1, down은 y-1 이 되도록 조건문을 작성한다.
    for(let i = 0 ; i < keyinput.length; i++){
        if(keyinput[i] === "right") x++;
        if(keyinput[i] === "left") x--;
        if(keyinput[i] === "up") y++;
        if(keyinput[i] === "down") y--;
        
    }
    return [x, y]
}
💡 코드 풀이
  • 하지만 여전히 테스트케이스 2번은 통과되지 않았다.
  • 사람들의 질문을 살펴보니 → 해당 테스트케이스에 반례가 있다는 점을 깨달았다. 그리고 코드에 이를 반영했다.

마지막 풀이

function solution(keyinput, board) {
    //1. [0,0]에서 시작하므로
    let x = 0;
    let y = 0;
    
    //2. board에 크기도 정해져 있기때문에 마찬가지로, x/y가 갈 수 있는 범위를 지정한다.
    let xRange = (board[0] / 2);
    let yRange = (board[1] / 2);
    
    //3. keyinput을 순회하며 right라면 x+1, left는 x-1, up은 y+1, down은 y-1 이 되도록 조건문을 작성한다.
   /* 4. 반례를 생각하자 
    -> 이미 xRange 혹은 yRange에 닿아있다면 이동할 수 없다 = 즉 x/yRange 보다 x/y값이 작은 경우에만 이동 가능하다. 
    -> 따라서 해당 조건을 넣어준다. */
    for(let i = 0 ; i < keyinput.length; i++){
        if(keyinput[i] === "right" && x + 1 < xRange) x++;
        if(keyinput[i] === "left" && x - 1 > -xRange) x--;
        if(keyinput[i] === "up" && y+1 < yRange) y++;
        if(keyinput[i] === "down" && y-1 > -yRange) y--;
        
    }
    return [x, y]
}

💡 배워야 할 점
  • 반례, 즉 엣지 케이스를 항상 염두하자 !!!!!!!
profile
한입 크기로 베어먹는 개발지식 🍰

0개의 댓글