몸과 마음이 건전한 SW 개발자

프로그래머스 [Lv. 3] n + 1 카드게임 {언어 : JavaScript} 본문

알고리즘/풀었지만 다시 보기

프로그래머스 [Lv. 3] n + 1 카드게임 {언어 : JavaScript}

스위태니 2024. 9. 13. 21:25

문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/258707

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

정답 코드

function solution(coin, cards) {
    const n = cards.length;
    const cardSum = n + 1;
    const myCards = cards.slice(0, n/3);
    const deck = cards.slice(n/3);
    const coinCards = [];
    
    // [1] 내 손에 있는 카드 중에서 확인
    const firstCheck = () => {
        const lenM = myCards.length;
        for (let i = 0; i < lenM - 1; i++) {
            const cardI = myCards[i];
            for (let j = i+1; j < lenM; j++) {
                const cardJ = myCards[j];
                if (cardI + cardJ === cardSum) {
                    return [i, j];
                }
            }
        }
        return [-1, -1];
    }
    
    // [2] 내 손에 있는 카드 뭉치와 코인으로 뽑은 카드 뭉치 사이에서 확인
    const secondCheck = () => {
        const lenCC = coinCards.length;
        const lenM = myCards.length;
        for (let i = 0; i < lenM; i++) {
            const mci = myCards[i];
            for (let j = 0; j < lenCC; j++) {
                const ccj = coinCards[j];
                if (mci + ccj === cardSum) {
                    return [i, j];
                }
            }
        }
        return [-1, -1];
    }
    
    // [3] 뽑은 카드 뭉치 중에서 확인
    const thirdCheck = () => {
        const lenCC = coinCards.length;
        for (let i = 0; i < lenCC - 1; i++) {
            const cci = coinCards[i];
            for (let j = i+1; j < lenCC; j++) {
                const ccj = coinCards[j];
                if (cci + ccj === cardSum) {
                    return [i, j];
                }
            }
        }
        return [-1, -1]
    }
    
    // 라운드 진행하기
    let round = 1;
    while (deck.length > 0) {
        // 라운드 시작
        // coinCards에 카드 두 장 넣기
        for (let k = 0; k < 2; k++) {
            coinCards.push(deck.shift());
        }
        // 내 손에서 해결 가능한지 확인
        const mcl = myCards.length;
        if (mcl >= 2) {
            const [fi, fj] = firstCheck();
            if (fi === -1 && fj === -1) {
                const [ci, cj] = secondCheck();
                if (ci === -1 && cj === -1) {
                    const [ti, tj] = thirdCheck();
                    if (ti === -1 && tj === -1) {
                        break;
                    } else {
                        if (coin < 2) {
                            break;
                        }
                        coinCards.splice(ti, 1);
                        coinCards.splice(tj-1, 1);
                        coin -= 2;
                    }
                } else {
                    if (coin < 1) {
                        break;
                    }
                    coin--;
                    myCards.splice(ci, 1);
                    coinCards.splice(cj, 1);
                }
            } else {
                myCards.splice(fi, 1);
                myCards.splice(fj-1, 1);
            }
        } else if (mcl === 1) {
            const [ci, cj] = secondCheck();
            if (ci === -1 && cj === -1) {
                const [ti, tj] = thirdCheck();
                if (ti === -1 && tj === -1) {
                    break;
                } else {
                    if (coin < 2) {
                        break;
                    }
                    coinCards.splice(ti, 1);
                    coinCards.splice(tj-1, 1);
                    coin -= 2;
                }
            } else {
                if (coin < 1) {
                    break;
                }
                coin--;
                myCards.splice(ci, 1);
                coinCards.splice(cj, 1);
            }
        } else {
            const [ti, tj] = thirdCheck();
            if (ti === -1 && tj === -1) {
                break
            } else {
                if (coin < 2) {
                    break;
                }
                coinCards.splice(ti, 1);
                coinCards.splice(tj-1, 1);
                coin -= 2;
            }
        }
        round++;
    }
    return round;
}

풀이 방법

1. 초기 설정

  • 카드 배열에서 플레이어의 카드(myCards)와 덱(deck)을 분리한다.
  • coinCards는 빈 배열로 초기화한다.
  • cardSum은 카드의 합 목표로 설정다.

2. 카드 쌍 찾기 함수들

  • firstCheck는 내 카드에서 목표 카드 쌍을 찾습니다.
  • secondCheck는 내 카드와 coinCards에서 쌍을 찾습니다.
  • thirdCheck는 coinCards에서 쌍을 찾습니다.

3. 라운드 진행

  • 매 라운드마다 덱에서 2장을 coinCards에 추가합니다.
  • 카드 쌍을 찾기 위해 내 카드, coinCards, 그리고 카드 쌍 중에서 확인합니다.
  • 해결할 수 없는 경우, 동전 부족 시 또는 카드 쌍이 없는 경우 라운드를 종료합니다.

느낀점

  • 일단 풀긴했는데 리펙토링을 하면 좋을 것 같기는 하다.