[프로그래머스] 무인도 여행 - JavaScript

문제 출처

Lv.2 무인도 여행 - JavaScript

문제 설명

메리는 여름을 맞아 무인도로 여행을 가기 위해 지도를 보고 있습니다. 지도에는 바다와 무인도들에 대한 정보가 표시돼 있습니다. 지도는 1 x 1크기의 사각형들로 이루어진 직사각형 격자 형태이며, 격자의 각 칸에는 ‘X’ 또는 1에서 9 사이의 자연수가 적혀있습니다. 지도의 ‘X’는 바다를 나타내며, 숫자는 무인도를 나타냅니다. 이때, 상, 하, 좌, 우로 연결되는 땅들은 하나의 무인도를 이룹니다. 지도의 각 칸에 적힌 숫자는 식량을 나타내는데, 상, 하, 좌, 우로 연결되는 칸에 적힌 숫자를 모두 합한 값은 해당 무인도에서 최대 며칠동안 머물 수 있는지를 나타냅니다. 어떤 섬으로 놀러 갈지 못 정한 메리는 우선 각 섬에서 최대 며칠씩 머물 수 있는지 알아본 후 놀러갈 섬을 결정하려 합니다.

지도를 나타내는 문자열 배열 maps가 매개변수로 주어질 때, 각 섬에서 최대 며칠씩 머무를 수 있는지 배열에 오름차순으로 담아 return 하는 solution 함수를 완성해주세요. 만약 지낼 수 있는 무인도가 없다면 -1을 배열에 담아 return 해주세요.

제한 사항
  • 3 ≤ maps의 길이 ≤ 100
    • 3 ≤ maps[i]의 길이 ≤ 100
    • maps[i]는 ‘X’ 또는 1 과 9 사이의 자연수로 이루어진 문자열입니다.
    • 지도는 직사각형 형태입니다.
예시

입출력 예

maps return
[“X591X”,”X1X5X”,”X231X”, “1XXX1”] [1, 1, 27]
[“XXX”,”XXX”,”XXX”] [-1]
풀이
function solution(maps) {
  // 배열 안 문자열을 배열로 변환해준다.
  // ["X591X","X1X5...] -> [["X", "5", "9" ...] ...]
  const newMap = maps.map((n) => n.split(""));

  // 상 하 좌 우 좌표를 미리 셋팅해둔다.
  const dx = [1, 0, -1, 0];
  const dy = [0, 1, 0, -1];

  function DFS(x, y, num) {
    
    // 들어온 num은 현재 String이므로 숫자로 변환해준다.
    let sum = Number(num);

    // 설정해둔 좌표 배열을 통해 상 하 좌 우를 탐색한다.
    for (let i = 0; i < 4; i++) {
      const nx = x + dx[i];
      const ny = y + dy[i];

      // 지도를 벗어나지 않는지 판단한다.
      if (nx >= 0 && ny >= 0 && nx < newMap.length && ny < newMap[0].length) {
        
        // 지도를 벗어나지 않고 "X"가 아닌 곳을 찾는다면
        if (newMap[nx][ny] !== "X") {
          
          // 식량 수를 저장하고
          const next = newMap[nx][ny];

          // 그 곳을 "X"로 변환하고
          newMap[nx][ny] = "X";

          // DFS를 통해 그 좌표부터 다시 탐색을 한다.
          // 그리고 그 리턴 값을 sum에 더해준다.
          sum += DFS(nx, ny, next);
        }
      }
    }

    // 최종적으로 다 더해진 sum을 리턴한다.
    return sum;
  }

  const answer = [];

  // 이중 포문을 통해 하나씩 살펴본다.
  for (let i = 0; i < newMap.length; i++) {
    for (let j = 0; j < newMap[0].length; j++) {
      
      // "X"가 아닌 곳을 찾게된다면
      if (newMap[i][j] !== "X") {

        // 일단 현재 수를 저장해둔다.
        const start = newMap[i][j];

        // 그 후 그 곳을 X로 변환한다.
        newMap[i][j] = "X";

        // DFS(x좌표, y좌표, 식량 수)를 실행하고
        // 그에 대한 반환 값을 answer에 push한다.
        answer.push(DFS(i, j, start));
      }
    }
  }

  // 만약 answer의 길이가 0이라면 [-1]을 리턴한다.
  // 아니라면 오름차순으로 정렬 후 리턴해준다.
  return answer.length ? answer.sort((a, b) => a - b) : [-1];
}
정리

DFS를 활용한 완전탐색 문제풀이였습니다. 이전 피로도 문제와 비슷하니 참고하시면 좋겠네요!
사용된 메서드와 문법에 대해 더 공부하고 싶으신 분은 링크를 클릭해주세요!

map() 메서드 - MDN
split() 메서드 - MDN

피드백은 언제나 환영입니다. 😊