오랜만에 프로그래머스 입문 문제를 풀었다. 확실히 입문 문제 90% 이상 넘어가니 난이도가 확 올라가더라(그냥 내가 못하는거임)
일단 지뢰의 위치들을 mines 배열에 넣어주었다. 그리고 이제 그 좌표를 중심으로 주변 8칸에 표시만 해주면 되는데, 여기서 뇌정지가 왔다.
'어떻게 주변 8칸을 구하지?🤔'라는 막막함에 프로그래머스 질문 목록도 찾아보고, 구글링도 해본 결과... 델타 배열
이라는 유용한 계산법이 있는게 아닌가! 앞으로 알고리즘에서 2차원 배열과 관련된 문제가 많이 나올 것 같은데, 이참에 한번 정리해보고자 한다. (나중에 두고두고 봐야지)
델타 배열은 2차원 배열([ [],[] ... ]
)에서 특정 위치의 이동을 쉽게 처리하기 위한 배열로, 특히 8방향(상하좌우+대각선)을 탐색할 때 유용하다. 즉, 2차원 배열에서 특정 위치에서 여러 방향을 탐색할 때, if문을 여러 개 쓰는 것보다 반복문 하나로 해결할 수 있도록 해주는 것이 델타 배열이다.
const directions = [
[-1, 0], [1, 0], // 상, 하
[0, -1], [0, 1], // 좌, 우
[-1, -1], [-1, 1], [1, -1], [1, 1] // 대각선 (좌상, 우상, 좌하, 우하)
];
x, y
에서 이동 거리 dx, dy
를 더해서 이동//8방향 탐색
for (let [dx, dy] of directions) {
let nx = x + dx; // 새로운 행 위치
let ny = y + dy; // 새로운 열 위치
// 범위 체크 (배열 인덱스 벗어나지 않도록)
if (nx >= 0 && nx < board.length && ny >= 0 && ny < board.length) {
console.log(`이동 가능: (${nx}, ${ny})`);
}
}
if (nx >= 0 && nx < board.length && ny >= 0 && ny < board.length) {
// 유효한 좌표일 때만 작업 수행
}
for (let x = 0; x < n; x++) {
for (let y = 0; y < n; y++) {
if (board[x][y] === 1) { // 지뢰 발견
// 상
if (x > 0) board[x - 1][y] = -1;
// 하
if (x < n - 1) board[x + 1][y] = -1;
// 좌
if (y > 0) board[x][y - 1] = -1;
// 우
if (y < n - 1) board[x][y + 1] = -1;
// 좌상
if (x > 0 && y > 0) board[x - 1][y - 1] = -1;
// 우상
if (x > 0 && y < n - 1) board[x - 1][y + 1] = -1;
// 좌하
if (x < n - 1 && y > 0) board[x + 1][y - 1] = -1;
// 우하
if (x < n - 1 && y < n - 1) board[x + 1][y + 1] = -1;
}
}
}
//델타 배열 정의
const directions = [
[-1, 0], [1, 0], [0, -1], [0, 1], // 상, 하, 좌, 우
[-1, -1], [-1, 1], [1, -1], [1, 1] // 좌상, 우상, 좌하, 우하 (대각선)
];
for (let x = 0; x < n; x++) {
for (let y = 0; y < n; y++) {
if (board[x][y] === 1) { // 지뢰 발견
for (let [dx, dy] of directions) { // 8방향 탐색
let nx = x + dx;
let ny = y + dy;
if (nx >= 0 && nx < n && ny >= 0 && ny < n && board[nx][ny] === 0) {
board[nx][ny] = -1; // 위험지역 표시
}
}
}
}
}
방식 | 코드 길이 | 유지보수 용이성 | 실수 가능성 | 성능 |
---|---|---|---|---|
직접 구현 | 길다 | 어렵다 | 높다 | 보통 |
델타 배열 | 짧다 | 쉽다 | 낮다 | 빠르다 |