
const fs = require('fs');
const path = process.platform === 'linux' ? '/dev/stdin' : 'Wiki\\input.txt';
const inputs = fs.readFileSync(path).toString().trim().split('\n');
const n = Number(inputs[0]);
const k = Number(inputs[1]);
const apples = inputs.slice(2, 2 + k);
const infos = inputs.slice(3 + k).map((it) => it.split(' '));
// 상 좌 하 우
const dx = [-1, 0, 1, 0];
const dy = [0, -1, 0, 1];
// 맵 생성
const map = Array.from({ length: n }).map(() =>
Array.from({ length: n }).fill('.')
);
// 맵 출력
const printMap = (...param) => {
console.log(...param);
for (let i = 0; i < n; i++) console.log(map[i].join(' '));
};
// 사과 생성
for (const apple of apples) {
const [x, y] = apple.split(' ').map(Number);
map[x - 1][y - 1] = 'A';
}
// 뱀 시작 위치 설정
map[0][0] = 'S';
let time = 0;
let d = 3;
let infoIdx = 0;
const q = [[0, 0]];
while (true) {
const [x, y] = q.at(-1);
const nx = x + dx[d];
const ny = y + dy[d];
if (nx < 0 || ny < 0 || nx === n || ny === n) break;
if (map[nx][ny] === 'S') break;
if (map[nx][ny] === 'A') {
map[nx][ny] = 'S';
q.push([nx, ny]);
} else if (map[nx][ny] === '.') {
const [px, py] = q.shift();
map[px][py] = '.';
map[nx][ny] = 'S';
q.push([nx, ny]);
}
time += 1;
if (infoIdx < infos.length && Number(infos[infoIdx][0]) === time) {
if (infos[infoIdx][1] === 'D') d = (d + 3) % 4;
if (infos[infoIdx][1] === 'L') d = (d + 5) % 4;
infoIdx += 1;
}
}
console.log(time + 1);
⏰ 소요한 시간 : 1시간
전형적인 시뮬레이션 유형
보드의 크기, 사과의 개수, k줄만큼 사과의 위치, 그 후 뱀의 방향 변환 횟수들을 입력받아준다.
2차원 배열에서 상하좌우를 움직여야 하는데 시계방향으로 움직이거나 반시계 방향으로 움직이기 때문에 상하좌우가 아닌 상좌하우 기준으로 이동할 수 있도록 dx, dy배열을 만들어줬다.
맵을 생성하는데 초기값은 .으로 세팅해두었다.
그 후 사과의 위치를 순회하면서 사과의 위치에 A라는 값을 넣어주고, 뱀의 시작 위치에도 S값을 넣어주었다.
그 후 시간을 기록할 변수 time, 현재 방향을 나타내는 d, 그리고 현재 순회하고 있는 방향 변환 인덱스 infoIdx와 뱀의 위치를 기록할 q를 배열을 만들어주고 초기값 0, 0을 넣어주었다.
그 후 무한 반복하며 뱀을 이동시켜준다. 큐의 마지막요소를 뽑아와 현재 뱀의 머리가 있는 좌표를 x, y로 두고 방금 선언한 dx, dy배열에 현재 바라보고 있는 방향 d를 넣어 뱀이 나아갈 좌표를 nx와 ny로 둔다.
만약 벽이라면 즉, 범위를 벗어나거나, 나아갈 좌표가 S 즉, 자기 몸통이라면 게임이 종료되므로 break를 걸어준다.
앞으로 전진할 수 있는데 전진할 칸에 사과가 있다면 해당 위치를 S로 바꾸고, 큐에 넣어준다.
만약 사과가 없다면 큐의 맨 앞요소 즉 꼬리를 제거해 해당 좌표를 .으로 변경하고, 나아갈 칸을 S로 변경하면 된다.
그리고 n초가 지났을 때, 방향변환을 해야해야 한다면 d에 1을 더해주거나(왼쪽) 1을 빼줘야(오른쪽) 한다. 이 때 d 값이 음수가 되는 것을 막기 위해 4를 더해주고, 1을 더하거나 뺀 뒤 4로 나눈 나머지를 d로 변경하면 방향을 쉽게 바꿀 수 있다. 방향을 바꾸고 방향 인덱스도 1증가 시켜준다.
마지막으로 정답을 출력..!
그리고 맵을 출력하는 함수를 사용하니 예외찾기가 편하더라...! 최고
한 번에 맞춰서 너무 뿌듯하다..!