본문 바로가기
코딩테스트

[프로그래머스/해시] 위장 (Kotlin)

by 굿햄 2023. 4. 15.

문제

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

 

프로그래머스

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

programmers.co.kr

 

사용한 개념

  • HashMap
  • 경우의 수 공식

 

답안

fun solution(clothes: Array<Array<String>>): Int {
    return clothes
        // 1. 옷의 종류로 그룹화
        .groupBy { array ->
            array[1]
        }
        // 2. Map 내의 value값을 Collection으로 반환
        .values
        // 3. 곱셈 연산 누적
        .fold(1) { acc, list ->
            acc * (list.size + 1)
        // 4. 모두 안 입었을 경우 제외
        } - 1 
}

 

풀이

해당 문제는 옷을 조합할 수 있는 경우의 수를 찾는 문제로, 우선 옷의 종류별로 개수가 몇 개인지 파악해야 합니다.

 

문제에서 함수로 넘기는 파라미터의 형식은 Array<Array<String>>으로 Array<String>이 하나의 아이템에 해당합니다.

코드로 나타내면 아래와 같습니다.

val clothes = arrayOf( arrayOf("yellowhat", "headgear"), arrayOf("bluesunglasses", "eyewear"), arrayOf("green_turban", "headgear"))

 

이를 Java에서 HashMap, Kotlin 내에서 Map을 활용하여, 옷의 종류를 key값으로 사용하여 각 아이템을 value에 리스트 형식으로 삽입할 수 있습니다.

Map<category: String, item: List<Array<String>>>

 

문제에서 제시한 2차원 배열을 순회하며, Map에 삽입이 가능하나,
Kotlin Collections의 groupBy 함수를 활용하면, 그룹화의 기준의 정의하여 value값에 아이템을 리스트화하여 위의 형식을 쉽게 만들 수 있습니다.

 

그 후, 옷의 종류별로 옷의 개수를 파악하기 위해 Map의 values 프로퍼티에 접근하여 Collection을 가져옵니다.

 

그러면 아래와 같은 형식으로 변환됩니다.

[["yellowhat","green_turban"],["bluesunglasses"]]

 

한 종류에 옷을 0개 입는 경우도 있으므로 아래처럼 생각할 수 있으며, 

[["yellowhat","green_turban","null"],["bluesunglasses","null"]]

'경우의 수' 해당 일이 일어날 각각의 경우를 곱하는 것이므로, 3 * 2 라고 볼 수 있으며, 모두 벗는 경우를 빼야하므로 최종 식은 3 * 2 - 1이 됩니다.

 

위의 코드에서는 이 방법을 응용하여 [["yellowhat","green_turban"],["bluesunglasses"]]에서 fold 함수를 사용하여 초기값을 1로, 누적 연산을 ${리스트의 크기 + 1}로 적용하여 연산하였습니다.

 


ⓒ 굿햄 2022. daryeou@gmail.com all rights reserved.

 

댓글