프로그래머스 LEVEL 3(기둥과 보 설치)

image

  • 사용 언어 : javascript

  • 해결 날짜 : 2023-05-20

  • 해결 방법 :

    • Set 자료구조를 활용해 문제 해결
      • 설치해야 하는 경우(b === 1),
        • 기둥인 경우 바닥 위에 있거나 보의 한쪽 끝 부분 위에 있거나, 또는 다른 기둥 위에 있는 경우 설치 가능
        • 보인 경우 한쪽 끝 부분이 기둥 위에 있거나, 또는 양쪽 끝 부분이 다른 보와 동시에 연결되어 있는 경우 설치 가능
      • 제거해야 하는 경우(b === 0),
        • set에서 제거했을 때 나머지 set의 key들에 대한 유효성 검사 후 유효하지 않을 때 제거한 key값 다시 set에 추가
      • Set -> Array 변환 및 정렬 후 반환
  • 회고 :

    • 처음에 작성한 코드

      function solution(n, build_frame) {
        const set = new Set();
      
        const isValid = (x, y, a) => {
          if (a === 0) {
            if (
              y === 0 ||
              set.has(`${x}${y - 1}${0}`) ||
              set.has(`${x - 1}${y}${1}`) ||
              set.has(`${x}${y}${1}`)
            ) {
              return true;
            }
          } else {
            if (
              set.has(`${x}${y - 1}${0}`) ||
              set.has(`${x + 1}${y - 1}${0}`) ||
              (set.has(`${x - 1}${y}${1}`) && set.has(`${x + 1}${y}${1}`))
            ) {
              return true;
            }
          }
      
          return false;
        };
      
        build_frame.forEach(([x, y, a, b]) => {
          if (b === 1) {
            if (isValid(x, y, a)) {
              set.add(`${x}${y}${a}`);
            }
          } else {
            set.delete(`${x}${y}${a}`);
      
            for (const k of set) {
              const [X, Y, A] = k.split('').map((v) => +v);
      
              if (!isValid(X, Y, A)) {
                set.add(`${x}${y}${a}`);
                break;
              }
            }
          }
        });
      
        return Array.from(set)
          .map((v) => v.split('').map((e) => +e))
          .sort((a, b) =>
            a[0] === b[0] ? (a[1] === b[1] ? a[2] - b[2] : a[1] - b[1]) : a[0] - b[0],
          );
      }
      
    • 테스트 케이스 3 ~ 9를 제외한 전부를 실패했다..

      image

    • 원인은 set에서 array로 변환하는 과정과 split 하여 [X, Y, A]로 변환하는 과정에서 ‘‘를 기준으로 split했기 때문이었다.
    • 각 X, Y는 한 자릿수에 국한된 것이 아닌 5 ~ 100까지의 숫자이기에 x, y, a를 set에 add, delete할 때 ‘,’로 구분하도록 변경하였다. 그 결과 성공!

      image

    • 조건을 잘 읽자..!
  • 코드

    function solution(n, build_frame) {
      const set = new Set();
    
      const isValid = (x, y, a) => {
        if (a === 0) {
          if (
            y === 0 ||
            set.has(`${x},${y - 1},${0}`) ||
            set.has(`${x - 1},${y},${1}`) ||
            set.has(`${x},${y},${1}`)
          ) {
            return true;
          }
        } else {
          if (
            set.has(`${x},${y - 1},${0}`) ||
            set.has(`${x + 1},${y - 1},${0}`) ||
            (set.has(`${x - 1},${y},${1}`) && set.has(`${x + 1},${y},${1}`))
          ) {
            return true;
          }
        }
    
        return false;
      };
    
      build_frame.forEach(([x, y, a, b]) => {
        if (b === 1) {
          if (isValid(x, y, a)) {
            set.add(`${x},${y},${a}`);
          }
        } else {
          set.delete(`${x},${y},${a}`);
    
          for (const k of set) {
            const [X, Y, A] = k.split(',').map((v) => +v);
    
            if (!isValid(X, Y, A)) {
              set.add(`${x},${y},${a}`);
              break;
            }
          }
        }
      });
    
      return Array.from(set)
        .map((v) => v.split(',').map((e) => +e))
        .sort((a, b) => (a[0] === b[0] ? (a[1] === b[1] ? a[2] - b[2] : a[1] - b[1]) : a[0] - b[0]));
    }
    
  • 출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges