본문 바로가기

코딩 테스트/DFS

[프로그래머스] 광물 캐기 Lv.2 with Kotlin

문제

다음과 같이 3가지 종류의 곡괭이와 광물이 있다.

각 곡괭이로 광물을 캘 때, 위와 같은 피로도가 소모가 된다.

 

주어진 광물을 순서대로 캘 때, 최소한의 피로도를 구하는 문제

 

조건

  • 모든 곡괭이는 각각 5번만 사용 가능하다.
  • 한 번 선택한 곡괭이는 5번 사용할 때까지 바꿀 수 없다.
  • 곡괭이가 모두 소진되거나, 광물을 모두 캐면 종료

 

풀이 방법

  1. 다이아 : 25 , 철 : 5, 돌 : 1
  2. DFS로 모든 경우의 수 확인
  3. 피로도 = 현재 광물 / 사용중인 도구 (값이 0이면 1)

 

코드

class Solution {
    var answer: Int = 0
    val hash = hashMapOf("diamond" to 25, "iron" to 5, "stone" to 1)
    val tools = hashMapOf(0 to "diamond", 1 to "iron", 2 to "stone")
    
    fun solution(picks: IntArray, minerals: Array<String>): Int {
        func(picks, minerals, 0, 0)
        
        return answer
    }
    
    fun func(picks: IntArray, minerals: Array<String>, index: Int, fatigue: Int){
        // 장비를 다 사용하였거나, 광물을 다 캤다면 종료
        if(index == minerals.size || picks.sum() == 0){
            answer = if(answer == 0) fatigue else Math.min(answer, fatigue)
            return
        }
        // 피로도가 최솟값이 아니면 종료
        if(answer != 0 && answer < fatigue) return
        
        for(i in 0..2){ // 0 : 다이아 , 1 : 철 , 2 : 돌
            if(picks[i] == 0) continue
            
            val picks_State = picks.copyOf()
            var index2 = index
            var fatigue2 = fatigue
            var count = 0 // 곡괭이 사용 횟수
            
            // 사용한 곡괭이 차감
            picks_State[i] -= 1
            
            // 채취
            // 곡괭이 5번 사용 or 광물을 다 캤다면 종료
            while(count < 5 && index2 != minerals.size){
                // 피로도 = 현재 광물 / 도구
                val f = hash[minerals[index2++]]!! / hash[tools[i]!!]!!
                
                fatigue2 += if(f == 0) 1 else f
                
                count++
            }
            
            func(picks_State, minerals, index2, fatigue2)
        }
    }
}