Algorithm
[백준] 7562번: 나이트의 이동 - Node.js (자바스크립트)
sqsung
2023. 5. 23. 13:36
1. 문제 ㅡ 7562번: 나이트의 이동(난이도: Silver I)
7562번: 나이트의 이동
체스판 위에 한 나이트가 놓여져 있다. 나이트가 한 번에 이동할 수 있는 칸은 아래 그림에 나와있다. 나이트가 이동하려고 하는 칸이 주어진다. 나이트는 몇 번 움직이면 이 칸으로 이동할 수
www.acmicpc.net
2. 풀이 ㅡ Node.js (자바스크립트)
const [N, ...input] = require('fs').readFileSync('/dev/stdin').toString().trim().split('\n');
const solution = input => {
// 나이트가 이동할 수 있는 방향들
const moves = [[-1, 2], [-2, 1], [-2, -1], [-1, -2], [1, -2], [2, -1], [2, 1], [1, 2]];
const testCases = [];
const answers = [];
// 테스트 케이스들 숫자 타입 정보를 가진 객체로 변경 및 testCases 배열에 저장
for (let i = 0; i < +N; i++) {
// TypeError 이유 ▽
const [board, start, end] = input.splice(0, 3);
const tcObject = { board: +board, start: start.split(' ').map(val => +val), end: end.split(' ').map(val => +val) };
testCases.push(tcObject);
}
// bfs 탐색
for (let i = 0; i < +N; i++) {
const { board, start, end } = testCases[i];
const checked = Array.from({ length: board }, () => Array.from({ length: board }, () => false));
const queue = [[...start, 0]];
while (queue.length) {
const [x, y, count] = queue.shift();
// x, y 값이 end의 x, y와 같으면 누적된 count 저장 및 while문 break
if (x === end[0] && y === end[1]) {
answers.push(count);
break;
}
checked[y][x] = true;
moves.forEach(move => {
const xPos = x + move[0];
const yPos = y + move[1];
if (xPos < 0 || yPos < 0 || xPos >= board || yPos >= board || checked[yPos][xPos]) return;
checked[yPos][xPos] = true;
queue.push([xPos, yPos, count + 1]);
});
}
}
return answers.join('\n');
};
console.log(solution(input));
2-1. 풀이 설명
백준에서 BFS 유형 문제를 여러 개 풀어봤다면 금방 어떻게 풀어야할지 감이 올만한 문제다. 다른 문제에서는 주로 좌우상하로 인접한 칸만 확인했던 것과 달리, 이번 문제에서는 나이트가 이동할 수 있는 모든 칸을 확인하면 된다.
우선 각 테스트 케이스를 객체(tcObject)로 정리했다. 각 tcObject에는 나이트의 시작점과 목표점, 그리고 보드의 크기 정보를 저장해두었다. 이후 각 tcObject를 순회하면서 while문을 사용해 BFS 탐색을 했다. while문 내부에서는 현재 x, y 값이 종료점의 x, y와 일치하는지 확인하고, 일치하면 누적된 count 값을 answers 배열에 담아주고, 일치하지 않는 경우에는 해당 위치에서 또 나이트가 이동할 수 있는 칸을 queue에 담아 탐색을 반복했다.
2-2. 회고

- '체점현황' 탭을 누르고 언어를 node.js로 설정하면 많은 제출에 런타임 에러(TypeError)가 난걸 확인할 수 있다. 나 또한 VS Code에서는 아무 문제 없이 작동하는 코드가 제출만 하면 런타임 에러(TypeError)가 나서 답답했다.
- 자바스크립트로 제출한 다른 개발자 분들의 경우 왜 런타임 에러(TypeError)가 났는지 정확히는 모르지만, 나 같은 경우에는 테스트 케이스 정보를 정리하는 과정에서 splice의 조건을 잘못 줘서 그렇게 됐다 (코드 블럭에서 'TypeError 이유' 부분 확인).
- 정확히는 input에서 각 테스트 케이스를 분리하기 위해 splice 메서드를 사용했는데, 모든 테스트 케이스가 3줄이므로 splice(0, 3)하면 되는 걸 이상하게 splice(0, N)을 해줬다. 우연히도 문제에서 제공한 테스트 케이스에서는 N 또한 3이었으므로 문제없이 돌아갔지만, 테스트 케이스의 개수를 1개로 줄이고 돌려보고 나서야 문제를 찾았다.