프로그래머스 0단계 - 캐릭터의 좌표

이종현·2024년 1월 10일
0

코딩테스트

목록 보기
10/24
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]까지 이동할 수 있습니다.

제한사항

  • board은 [가로 크기, 세로 크기] 형태로 주어집니다.
  • board의 가로 크기와 세로 크기는 홀수입니다.
  • board의 크기를 벗어난 방향키 입력은 무시합니다.
  • 0 ≤ keyinput의 길이 ≤ 50
  • 1 ≤ board[0] ≤ 99
  • 1 ≤ board[1] ≤ 99
  • keyinput은 항상 updownleftright만 주어집니다.

입출력 예

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

1. 문제 이해

  • 캐릭터는 주어진 board의 정중앙에 배치된다.
  • 총 board사이즈는 가로 세로 100을 넘지 않으며 이동은 위, 아래, 왼쪽, 오른쪽으로 한 칸씩 움직인다.
  • board를 넘어가는 움직임이 실행될 때는 board의 끝에 머무르게 된다.
  • input은 가로 10^2, 세로 10^2 이기 때문에 웬만한 시간복잡도로 풀어도 괜찮을 것 같다.

2. 접근 방법

  • 직관적으로 생각하기
    • 정중앙에 있을 때 board의 왼쪽 or 오른쪽 사이즈를 구한다.
    • 각 움직임에 따라 조건문을 구현해서 좌표가 얼마나 이동되는지를 구한다.
    • board를 넘어가는 움직임에 대한 조건문을 구현해서 넘어가는 부분에 대한 처리를 한다.
    • 최종적으로 움직임이 완료된 좌표를 리턴한다.

3. 코드 설계

  • 직관적으로 생각하기
    • let x = 0
    • let y = 0
    • const xRange = (board[0] - 1 ) / 2
    • const yRange = ([board[1] - 1 ) / 2
    • const coordinate = [x, y]
    • for(let i = 0; i < keyinput.lenght; i++) 로 반복을 돌면서
    • if(keyinput[i] === ‘left’) 일 때 x -= 1 로 해서 정중앙이 [0, 0] 일때 부터 시작해서 keyinput에 따라 좌표를 최종적으로 반영한다.
    • x ≤ -xRange return;

4. 코드 구현

function solution(keyinput, board) {
  let x = 0
  let y = 0
  const xRange = board[0] === 1 ? 0 : (board[0] - 1) / 2
  const yRange = board[1] === 1 ? 0 : (board[1] - 1) / 2
  let coordinate = [x, y]

  for (let i = 0; i < keyinput.length; i++) {
    switch (keyinput[i]) {
      case 'left':
        x -= 1
        break
      case 'right':
        x += 1
        break
      case 'up':
        y += 1
        break
      case 'down':
        y -= 1
        break
      default:
        return
    }
    if (x < -xRange) x = -xRange
    if (x > xRange) x = xRange
    if (y > yRange) y = yRange
    if (y < -yRange) y = -yRange
  }
  coordinate = [x, y]

  return coordinate
}

다른 사람 풀이

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;
}

회고

1차적으로 코드 구현을 완료하고 테스트를 돌렸는데, 테스트 8번에서 통과되지 못했다;; 그래서 여러가지 경우를 고려해서 조건을 바꿔보고 코드의 위치를 바꿔보기도 하다가 답을 볼까하는 유혹에 빠지려고 할 때, 혹시 같은 고민을 하고 있는 사람이 있을까해서 구글링 했더니, 테스트 8번의 케이스에 대해서 누가 힌트를 남겨놓은 부분이 있었다. 그래서 해당 부분을 참고해서 코드 수정해서 해결했다.

profile
데이터리터러시를 중요하게 생각하는 프론트엔드 개발자

0개의 댓글