ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [CodeKata] 프로그래머스: 12.12(일), 카드 짝 맞추기
    Algorithm 2021. 12. 13. 01:49
    반응형

    🥋 Oooth More!! (Level 3) 

     

     

    🧮 풀이

    function solution(board, r, c) {
      let answer = 0;
      let cardPos = {};
      for (let x = 0 ; x < 4 ; x++) {
        for (let y = 0 ; y < 4 ; y++) {
          if (board[x][y] === 0) continue;
          const card = board[x][y];
          cardPos[card] = cardPos[card] ? [...cardPos[card], [x,y]] : [[x,y]]
        }
      }
    
      const findCard = () => {
        if (board[r][c] !== 0) return;
        for (let i = 0 ; i < 4 ; i++) {
          if (board[r][i] !== 0) {
            c = i;
            answer++;
            return;
          }
          if (board[i][c] !== 0) {
            r = i
            answer++;
            return;
          }
        }
        let pos;
        let dist = 7;
        Object.values(cardPos).flat().forEach(([x,y]) => {
          const nowDist = Math.abs(r-x) + Math.abs(c-y);
          if (nowDist < dist) {
            pos = [x,y]
            dist = nowDist
          }
        })
        r = pos[0]
        c = pos[1]
        answer += 2
      }
      
      let count = Object.keys(cardPos).length;
      
      while (count > 0) {
        findCard();
        const card = board[r][c];
        const [a,b] = cardPos[card];
        board[a[0]][a[1]] = board[b[0]][b[1]] = 0;
        r = r === a[0] ? b[0] : a[0]
        c = c === a[1] ? b[1] : a[1]
        answer += 2
        if (a[0] !== b[0]) answer++
        if (a[1] !== b[1]) answer++
        delete cardPos[card]
        count--
      }
      
      
      return answer;
    }

    1. answer 변수선언, cardPos 객체 좌표정보 저장

    • answer는 정답이자 키조작마다 횟수를 누적하는 변수, cardPos는 각 카드들의 2가지 좌표를 저장하는 객체이다.
    • board를 순회하며, 카드번호를 key로, 2곳의 좌표를 [[좌표1x, 좌표1y], [좌표2x, 좌표2y]] 형태의 valuecardPos에 저장했다.

     

    2. findCard() 함수 만들기

    • findCard() 함수는 현재좌표(r, c)에서 인접한 카드로 좌표를 이동시키기 위한 함수이다. 그렇기에, 현재 좌표값이 0이 아니면 별도의 동작 없이 return 시킨다.
    • 다음으로, 키조작을 1번만 하는 경우를 찾았다. 해당 행(r) 혹은 열(c)에 카드(0이 아닌 값)가 있으면 여기로 좌표를 바로 이동시킨다. 이 때는, 화살표 혹은 ctrl + 화살표 만으로 조작하므로 answer에 1을 더했다.
    • 위처럼 행 혹은 열에 카드가 없다면, cardPos에 남은 모든 좌표들을 Object.values()로 가져와서 현재 좌표에 가장 가까운 값을 찾았다.
    • pos는 가까운 좌표값을 저장하는 변수, dist는 가까움을 판정하기 위한 거리이다. 최대거리보다 1 많은 7로 초기설정하고 특정 좌표가 이보다 짧다면 pos에 좌표값을, dist는 그 좌표까지의 거리로 최신화한다.
    • 마지막으로, 최신화된 pos의 각 값으로 r과 c를 최신화하며, 여기서는 2번의 키조작이 필요하므로 answer에 2를 더한다.

     

    3. 모든 카드 짝맞추기

    • count는 우리가 찾아야 할 카드종류의 갯수이다. 그렇기에, Object.keys() 등으로 그 length 값만 찾아주면 된다.
    • while 반복문을 실행하며, 매 회차마다 count를 1씩 줄이면 된다. 처음으로 findCard()를 하는 이유는 커서가 카드짝으로 이동했을때는 당연하며, 맨 처음에도 특정 카드 위에 있지 않을수도 있으므로 가장 가까운 카드로 커서를 한 번 이동시킨다.
    • 해당 카드값을 card 변수에 저장한다. 이를 cardPos 에서 참조하면, 이 카드에 해당하는 좌표 2곳(a, b)이 나온다.
    • 우선 board의 두 좌표를 0으로 만들어 중복을 방지한다. 그리고, 좌표 2곳 중 현재좌표가 아닌 곳으로 (r, c)를 최신화한다.
    • answer에는 기본적으로 enter 조작인 2를 더한다. 그리고, x, y 좌표가 같은지 여부를 확인해 같지 않다면 1씩 더 더해준다.
    • cardPos의 card 프로퍼티를 제거해 중복을 방지하며, count를 1을 차감하며 다음 사이클로 넘어간다.

     

    내 풀이는, 카드 좌표들의 저장 / 인접한 다음 카드찾기 / 카드 짝맞추기 3가지 부분으로 만들어진 코드이다.

    43%만의 정답률을 보였으며, 모범답안을 보면서 어느 부분이 문제였을지 확인해야겠다.

     

     

    🖇 리뷰

    https://velog.io/@longroadhome/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV.3-%EB%B6%88%EB%9F%89-%EC%82%AC%EC%9A%A9%EC%9E%90-JS-iz8d5d6k

    반응형
Designed by Tistory.