본문 바로가기
개발/알고리즘 풀기

TIL 230413 테스트_지뢰찾기 맵 만들기

by 코딩하는짱구 2023. 4. 13.
반응형

지뢰찾기 맵 만들기

✅문제 

-지뢰 탐지가 필요해! (난 안필요해...)

 
지뢰 찾기 map은 N*N의 정사각형 모양으로 각 칸에는 숫자가 들어가 있거나 지뢰가 들어가 있다. 빈 칸에는 숫자 0이 들어있다고 생각하자.
map의 어떤 칸에 적혀 있는 숫자는, 그 칸과 인접해 있는 여덟 개의 칸 중에서 지뢰가 들어 있는 칸이 몇 개인지를 나타내 준다. 물론 인접한 칸이 map 내부에 있는 경우에 대해서만 생각하면 된다. 예제를 보면 더 잘 이해할 수 있을 것이다.
이번 문제는 조금 업그레이드 된 지뢰 찾기로, 한 칸에 한 개의 지뢰가 있는 것이 아니고, 한 칸에 여러 개(1 이상 9 이하)의 지뢰가 묻혀 있는 게임이다. 따라서 map의 어떤 칸에 적혀 있는 숫자는, 그 칸과 인접해 있는 여덟 개의 칸들에 들어 있는 지뢰의 총 개수가 된다.
르탄이는 map에서 지뢰에 대한 정보만이 주어졌을 때, map을 완성하고 싶다고 한다. N과 지뢰의 위치가 주어졌을 때, 르탄이를 도와서 지뢰 찾기 map을 완성하는 프로그램을 작성하시오.
입력 값:
let N = 5;
let arr1 = [
 ["1", ".", ".", ".", "."],
 [".", ".", "3", ".", "."],
 [".", ".", ".", ".", "."],
 [".", "4", ".", ".", "."],
  [".", ".", ".", "9", "."],
];

도출해야하는 값:

[[*, 4, 3, 3, 0], //*는 지뢰, 숫자는 인접8칸의 지뢰개수, 0은 없고, M은 인접지뢰 갯수가 10이상

[1, 4, *, 3, 0],

[4, 7, 7, 3, 0],

[4, *, M. 9, 9],

[4, 4, M, *, 9]]

 

✍문제풀이

1. 나의 접근방식 및 실패한 코드

 

접근 방식까진 좋았는데 x,y가 뭘 의미하는지, 좌표를 의미하는건 알겠는데 어떤식으로 움직이는지 파악이 안되서 힘들었다. 

let N = 5;
let arr1 = [
  ["1", ".", ".", ".", "."],
  [".", ".", "3", ".", "."],
  [".", ".", ".", ".", "."],
  [".", "4", ".", ".", "."],
  [".", ".", ".", "9", "."],
];

function solution(N, arr1) {
  let x = [1, -1, 0, 0, 1, 1, -1, -1];
  let y = [0, 0, 1, -1, 1, -1, 1, -1];
  let answer = [];

  for (let i = 0; i < N; i++) {
    let row = [];
    for (let j = 0; j < N; j++) {
      if (!isNaN(arr1[i][j])) {
        arr1[i][j] = "*";
        row.push(arr1[i][j]); //여기까지 지뢰를 *로 표시하기 성공!!
      } else {
        let sum = 0;
        for (let k = 0; k < 8; k++) {
          //k는 위치를 도는 것
          if (isNaN(arr1[i][j])) {
            let ni = i + x[k];
            let nj = j + y[k];
            if (ni >= 0 && ni < N && nj >= 0 && nj < N && !isNaN(arr1[ni][nj]))
              //(ni, nj) 가 범위 내에 있고, 위치값이 숫자인 경우만
              sum += parseInt(arr1[ni][nj]);
          }
        }
        row.push(sum >= 10 ? "M" : sum); //합친 값의 결과가 10이 넘으면 M으로 표기
      }
    }
    answer.push(row);
  }
  return answer;
}
console.log(solution(N, arr1));

 

2. 문제파악 및  해결한 코드

1. x,y가 행과 열을 의미한다는 점을 인지

2. x,y가 각각 8개이고 배열의 길이가 같다, 즉 (x,y)가 좌표다. 그 말은 (x[i],y[i])로 쭉쭉쭉 8방향을 돌아주는 것. 

let x = [1, -1, 0, 0, 1, 1, -1, -1]; 

let y = [0, 0, 1, -1, 1, -1, 1, -1]; 

3.좌표의 값이 왜 아래와 같은 형태가 되는지는 0,1,2를 직접 넣어보며 비교하고 원리를 알았다. 

잊지말고 새겨두자.

i + x[k]

4.이 부분은 x,y값에 -1값이 있기때문에 배열밖을 벗어날 수도 있으므로 범위내에 위치하도록 조건을 걸어주는 것. 

        i + x[k] >= 0 &&
            j + y[k] >= 0 &&
            i + x[k] < N &&
            j + y[k] < N &&

 

 

let N = 5;
let arr1 = [
  ["1", ".", ".", ".", "."],
  [".", ".", "3", ".", "."],
  [".", ".", ".", ".", "."],
  [".", "4", ".", ".", "."],
  [".", ".", ".", "9", "."],
];

function solution(N, arr1) {
  let x = [1, -1, 0, 0, 1, 1, -1, -1];
  let y = [0, 0, 1, -1, 1, -1, 1, -1];
  let answer = [];
  let b = 0;

  for (i = 0; i < N; i++) {
    let a = [];
    for (j = 0; j < N; j++) {
      if (!isNaN(arr1[i][j] / 1)) {
        a.push("*");
      } else {
        b = 0;
        for (k = 0; k < x.length; k++) {
          if (
            i + x[k] >= 0 &&
            j + y[k] >= 0 &&
            i + x[k] < N &&
            j + y[k] < N &&
            !isNaN(arr1[i + x[k]][j + y[k]] / 1)
          ) {
            b += Number(arr1[i + x[k]][j + y[k]]);
          }
        }
        if (b >= 10) {
          a.push("M");
        } else {
          a.push(b);
        }
      }
    }
    answer.push(a);
  }

  return answer;
}

console.log(solution(N, arr1));
반응형