본문 바로가기

코딩 테스트/Lv.3

[프로그래머스] 2024 KAKAO WINTER INTERNSHIP n + 1 카드게임 with Kotlin

문제

1~n 사이의 수가 적힌 카드가 하나씩 있는 카드 뭉치와 동전 coin개를 이용한 게임

  • 각 카드는 중첩되지 않는다. (카드 10장이 있다면 10장 다 다른 숫자)
  • 카드 뭉치에서 n/3개의 카드를 뽑아 갖는다. (카드 뭉치 앞에서부터 n/3개)
  • 각 라운드마다 카드 뭉치에서 2장씩 뽑고, 버리거나 동전을 사용하여 갖는다. (동전 하나 당 카드 한 장)
    • 카드 뭉치에 카드가 없다면 종료
  • 또한 라운드마다 내가 갖고 있는 카드에서 n+1이 되도록 카드 두 장을 제출하고 다음 라운드로 진행
    • 제출할 수 없다면 종료

(예시는 프로그래머스 참고 바랍니다.)

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

 

프로그래머스

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

programmers.co.kr

 

풀이 과정

  • 카드 뭉치는 앞에서부터 순서대로 나오기 때문에 Queue를 이용
  • 카드 두 장을 뽑은 뒤 내 카드와 n+1이 되면 동전 사용 후 제출
  • 라운드 당 2장씩 제출이므로 만일 카드 두 장이 모두 n+1이 가능하다면 나머지 한 장은 동전을 사용하여 내 카드에 저장 (다음 라운드들 중 하나에 사용)
  • 뽑은 카드가 조합이 불가능 하다면 temp에 따로 저장 후 내가 갖고 있는 카드들 중 n+1의 조합을 찾아 제출
  • 갖고 있는 카드에서 조합이 불가능하다면 보유 카드와 temp에 있는 카드 비교 후 동전 사용해서 제출
  • 만일 동전 2개 이상 보유중이며 위의 경우가 모두 불가능할 경우 temp내에서 n+1의 조합이 존재한다면 동전 2개 사용하여 제출
  • 위의 모든 과정을 거쳤지만 제출하지 못했다면 라운드 종료
  • 조합이 가능하지만 카드 뭉치가 다 떨어졌어도 종료 (다음 라운드 진행 불가)

( 개인 적인 풀이 과정임을 참고 부탁드립니다. )

 

코드

import java.util.*
class Solution {
    fun solution(coin: Int, cards: IntArray): Int {
        var answer: Int = 1
        val n = cards.size
        val myCard = mutableListOf<Int>()
        val cardList: Queue<Int> = LinkedList(cards.toList())
        var useCoin = 0
        
        // 내 카드 n/3
        for(i in 0 until n/3){
            myCard.add(cardList.poll())
        }
        
        val sum = n + 1
        val temp = mutableListOf<Int>() // 넘긴 카드 (추후에 coin으로 사용)
        
        while(true){
            var status = false // 카드 2장 제출 여부
            
            //카드 뭉치에 카드가 없다면
            if(cardList.size == 0) break
            
            //카드 두 장 뽑기
            val first = cardList.poll()
            val second = cardList.poll()
            
            //
            //카드 두 장 제출
            //
            // 첫 번째 카드와 n+1이 되는 카드
            if(myCard.contains(sum - first) && useCoin < coin){
                status = true
                useCoin += 1
                myCard.remove(sum - first)
            }
            else temp.add(first)
            
            // 두 번째 카드와 n+1이 되는 카드
            if(myCard.contains(sum - second) && useCoin < coin){
                useCoin += 1
                if(status) myCard.add(second)
                else{
                    status = true
                    myCard.remove(sum - second)
                }
            }
            else temp.add(second)
            
            // myCard에서 n+1 조합 찾기
            if(!status){
                for(card in myCard){
                    // 내 카드 내에 n+1이 있다면
                    if(myCard.contains(sum - card)){
                        status = true
                        
                        myCard.remove(card)
                        myCard.remove(sum - card)
                        break
                    }
                    //없으면 temp에서 coin 사용해서 갖다 쓰기
                    else if(temp.contains(sum - card) && useCoin < coin){
                        status = true
                        useCoin += 1
                        
                        myCard.remove(card)
                        temp.remove(sum - card)
                        break
                    }
                }
            }
            
            // coin도 2개 이상 남아있고 temp에서 n+1 조합이 있을 경우
            if(!status && coin - useCoin >= 2){
                for(tempCard in temp){
                    if(temp.contains(sum - tempCard)){
                        status = true
                        useCoin += 2
                        
                        temp.remove(tempCard)
                        temp.remove(sum - tempCard)
                        break
                    }
                }
            }
            
            //종료
            if(!status) break
            answer += 1
        }
        
        return answer
    }
}