본문 바로가기
알고리즘/백준

[노드JS/알고리즘] 백준 - 1063번 킹

by 프론트엔드 지식백과 2022. 6. 30.

[문제]

 

1063번: 킹

8*8크기의 체스판에 왕이 하나 있다. 킹의 현재 위치가 주어진다. 체스판에서 말의 위치는 다음과 같이 주어진다. 알파벳 하나와 숫자 하나로 이루어져 있는데, 알파벳은 열을 상징하고, 숫자는

www.acmicpc.net

 

[코드 풀이]

let [positions, ...commands] = require("fs")
  .readFileSync(process.platform === "linux" ? "/dev/stdin" : "input.txt")
  .toString()
  .trim()
  .split("\n");

// A-H열을 숫자로 라벨링
const pos = {
  A: 1,
  B: 2,
  C: 3,
  D: 4,
  E: 5,
  F: 6,
  G: 7,
  H: 8,
};

// 방향 정의
const move = {
  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 [kingPos, stonePos, N] = positions.split(" ");
const result = [];

// king, stone의 처음 위치 정의
let [x, y] = kingPos.split("");
let [x2, y2] = stonePos.split("");
y = Number(y);
y2 = Number(y2);

let king = [pos[x], y];
let stone = [pos[x2], y2];

for (let i = 0; i < N; i++) {
// 미리 정의해둔 move에 맞추어 킹 움직임
  const nx = king[0] + move[commands[i]][0];
  const ny = king[1] + move[commands[i]][1];

  if (0 < nx && nx <= 8 && 0 < ny && ny <= 8) { // 체스판 반경 지정(킹이 밖으로 나갈 경우 그 이동은 건너뜀)
    if (nx === stone[0] && ny === stone[1]) { //key point) 킹 위치가 돌이 있는 위치라면, 돌도 같은 방향으로 이동한다.
      const sx = stone[0] + move[commands[i]][0];
      const sy = stone[1] + move[commands[i]][1];
      if (0 < sx && sx <= 8 && 0 < sy && sy <= 8) { // 체스판 반경 지정(돌이 밖으로 나갈 경우 그 이동은 건너뜀)
        // 킹과 돌의 위치를 최신값으로 변경
        king = [nx, ny];
        stone = [sx, sy];
      } else {
        continue;
      }
    } else {
      // 돌이 없을 경우 킹의 위치만 최신값으로 변경
      king = [nx, ny];
    }
  } else {
    continue;
  }
}

// 출력을 위한 부분
const kingAns = Object.keys(pos).find((key) => pos[key] === king[0]);
const stoneAns = Object.keys(pos).find((key) => pos[key] === stone[0]);
result.push([kingAns, king[1]].join(""));
result.push([stoneAns, stone[1]].join(""));
console.log(result.join("\n"));

 

A-H열을 숫자로 두고, 로직을 짰다.

간단해 보였지만, 출력을 위한 부분에서 find를 써가며 답을 찾을 때, 더 단순한 방법은 없을까 고민했다.

다른 사람의 코드를 보니 .charCodeAt()-64로 위치를 지정해주었고,

출력 부분에서 String.fromCharCode(king[0] + 64)와 같이 불러와 주었다.

 

단순한 문법인데도 사용해 본적이 적어서 생각이 바로 나지 않았다.

문자열을 다룰 때, 종종 나오니까 외워둘것!!

 

[다른 풀이]

let [positions, ...commands] = require("fs")
  .readFileSync(process.platform === "linux" ? "/dev/stdin" : "input.txt")
  .toString()
  .trim()
  .split("\n");

const move = {
  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 [kingPos, stonePos, N] = positions.split(" ");

let [x, y] = kingPos.split("");
let [x2, y2] = stonePos.split("");
let king = [x.charCodeAt() - 64, Number(y)];
let stone = [x2.charCodeAt() - 64, Number(y2)];

for (let i = 0; i < N; i++) {
  const nx = king[0] + move[commands[i]][0];
  const ny = king[1] + move[commands[i]][1];

  if (0 < nx && nx <= 8 && 0 < ny && ny <= 8) {
    if (nx === stone[0] && ny === stone[1]) {
      const sx = stone[0] + move[commands[i]][0];
      const sy = stone[1] + move[commands[i]][1];
      if (0 < sx && sx <= 8 && 0 < sy && sy <= 8) {
        king = [nx, ny];
        stone = [sx, sy];
      } else {
        continue;
      }
    } else {
      king = [nx, ny];
    }
  } else {
    continue;
  }
}

const kingAns = `${String.fromCharCode(king[0] + 64)}${king[1]}`;
const stoneAns = `${String.fromCharCode(stone[0] + 64)}${stone[1]}`;

console.log(`${kingAns}\n${stoneAns}`);

 

출력하는 부분도 깔끔하게 바꾸어 보았다.

 

[결과]

코드는 짧아졌지만, 걸리는 시간은 똑같다. 메모리 사용만 조금 줄어든 것을 확인할 수 있다.

728x90