본문 바로가기

백준1063 - 킹 JS 본문

개발/algorithm

백준1063 - 킹 JS

자전하는명왕성 2023. 9. 21. 09:52

https://www.acmicpc.net/problem/1063

 

문제는 체스판에서 말을 움직이는 문제로, 비교적 자주 볼 수 있는 문제다.

조금 다른 점은 이 문제는 '말' 뿐만 아니라, '돌'도 주어지는데,

이 '돌'은 '말'이 미는 방향으로 움직일 뿐더러 이 또한 좌표 밖으로 벗어나서는 안된다는 제약이 주어진다.

 

나는 다음과 같이 문제 풀이 방식을 수립했다.

1. 먼저 처음 '말'과 '돌'의 위치로 주어지는 좌표가 'A8'와 같은 체스 좌표로 주어지기 때문에,

해당 체스 좌표를 x,y 좌표로 || x,y 좌표를 체스 좌표로 바꿀 수 있는 함수(정답 제출 시 필요)를 구현하고

 

2. '말'과 '돌'이 명령어에 따라 이동하는 좌표가 유효한 위치인지 확인할 수 있는 함수 구현,

3. 각 명령어에 따라 좌표가 어디로 움직이는지 가독성 좋게 사용할 수 있도록 명령어 객체를 구현했다.

 

작성한 코드

const fs = require('fs')
const input = fs.readFileSync(process.platform === "linux" ? "/dev/stdin":"입력.txt")
  .toString().trim().split('\n')

// 위치가 유효한지 검증하는 함수
const verify = (x,y) => {
  return x >= 0 && y >= 0 && 7 >= x && 7 >= y
}

// 체스 좌표 => x,y 좌표 || x,y 좌표 => 체스 좌표로 바꾸어 반환하는 함수
const findLocation = (el) => {
  const locationX = "ABCDEFGH"
  const locationY = "87654321"
  if(el === String(el)) {
    const [a,b] = el.split('')
    return [locationX.indexOf(a),locationY.indexOf(b)]
  } else {
    const [a,b] = el
    return locationX[a] + locationY[b]
  }
}

function solution(data) {
  // 명령어에 따른 위치 이동 내용을 담은 객체
  const commandTable = {
    "R" : [1,0],
    "L" : [-1,0],
    "B" : [0,1],
    "T" : [0,-1],
    "RT" : [1,-1],
    "LT" : [-1,-1],
    "RB" : [1,1],
    "LB" : [-1,1]
  }

  const [king, stone, N] = data.shift().split(' ')
  // 각 '말'과 '돌'의 체스 좌표를 x,y 좌표로 가져옴
  let [kingLocation, stoneLocation] = [findLocation(king), findLocation(stone)]

  for(let i = 0 ; i < N ; i ++) {
    // 명령어에 따른 이동 방향
    const [dx,dy] = commandTable[data[i]]
    // '말'의 다음 위치
    const [nextX, nextY] = [dx + kingLocation[0], dy + kingLocation[1]]
    // '말'의 다음 위치가 유효하지 않은 경우 패스
    if(!verify(nextX, nextY)) continue

    // 말의 다음 위치가 현재 돌의 위치와 같을 경우 (즉 '말'이 '돌'을 밀어내는 경우)
    if(nextX === stoneLocation[0] && nextY === stoneLocation[1]) {
      const [nextStoneX, nextStoneY] = [dx + stoneLocation[0], dy + stoneLocation[1]]
      
      // 돌을 밀어내게 되었을 때, 밀려진 돌의 위치가 유효하지 않은 경우 패스
      if(!verify(nextStoneX, nextStoneY)) continue
      
      // 돌을 밀어내도 두 '말'과 '돌' 모두 유효한 위치에 있을 경우 위치 저장
      kingLocation = [nextX, nextY]
      stoneLocation = [nextStoneX, nextStoneY]
    } else {
      // 돌을 밀어낼 필요없는 경우이므로 말의 위치만 저장
      kingLocation = [nextX, nextY]
    }
  }

  console.log([findLocation(kingLocation), findLocation(stoneLocation)].join('\n'))
}

solution(input)

 

'개발 > algorithm' 카테고리의 다른 글

백준2292 - 벌집 JS  (0) 2023.09.23
백준9324 - 진짜메시지 JS  (0) 2023.09.22
백준3107 - IPv6 JS  (0) 2023.09.20
백준3036 - 링 (유클리드 호제법) JS  (0) 2023.09.19
백준5567 - 결혼식 (그래프) JS  (0) 2023.09.18
Comments