코니는 매일 다른 옷을 조합하여 입는것을 좋아합니다.
예를 들어 코니가 가진 옷이 아래와 같고, 오늘 코니가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야합니다.
| 종류 | 이름 |
|---|---|
| 얼굴 | 동그란 안경, 검정 선글라스 |
| 상의 | 파란색 티셔츠 |
| 하의 | 청바지 |
| 겉옷 | 긴 코트 |
코니가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요.
| clothes | return |
|---|---|
| [["yellow_hat", "headgear"], ["blue_sunglasses", "eyewear"], ["green_turban", "headgear"]] | 5 |
| [["crow_mask", "face"], ["blue_sunglasses", "face"], ["smoky_makeup", "face"]] | 3 |
headgear에 해당하는 의상이 yellow_hat, green_turban이고 eyewear에 해당하는 의상이 blue_sunglasses이므로 아래와 같이 5개의 조합이 가능합니다.
1. yellow_hat
2. blue_sunglasses
3. green_turban
4. yellow_hat + blue_sunglasses
5. green_turban + blue_sunglasses
face에 해당하는 의상이 crow_mask, blue_sunglasses, smoky_makeup이므로 아래와 같이 3개의 조합이 가능합니다.
1. crow_mask
2. blue_sunglasses
3. smoky_makeup
💡 예
- [["yellow_hat", "headgear"], ["blue_sunglasses", "eyewear"], ["green_turban", "headgear"]]
- headgear: 2개, eyewear: 1개
→ 총 경우의 수:(2+1) * (1+1) - 1 = 5
typeCount 딕셔너리["headgear": 2, "eyewear": 1]contains + ! 사용!를 사용해 강제 언래핑 reduce + 클로저(value + 1)로 각 종류별 선택지 수를 구하고, reduce(1)로 곱해서 총 조합 수 계산 후, -1로 아무것도 착용하지 않는 경우를 제외import Foundation
func solution(_ clothes:[[String]]) -> Int {
var typeCount = [String: Int]()
// 종류별 개수 카운팅
for array in clothes {
if typeCount.contains { $0.0 == array[1] } {
typeCount[array[1]]! += 1
} else {
typeCount[array[1]] = 1
}
}
// 경우의 수 계산
return typeCount.reduce(1) { $0 * ($1.value + 1) } - 1
}
default: 사용! 사용은 지양, 훨씬 안전한 코드 작성import Foundation
func solution(_ clothes:[[String]]) -> Int {
var typeCount = [String: Int]()
// 종류별 개수 카운팅
for cloth in clothes {
typeCount[cloth[1], default: 0] += 1
}
// 경우의 수 계산
return typeCount.reduce(1) { $0 * ($1.value + 1) } - 1
}
| 항목 | 개선 전 | 개선 후 |
|---|---|---|
| 딕셔너리 값 증가 | contains + ! | default: 사용 |
| 가독성 | 낮음 | 더 명확하고 간결 |
| 안전성 | !로 crash 위험 있음 | 안전하게 처리 가능 |
| 성능 | contains는 느릴 수 있음 (O(n)) | 딕셔너리 직접 접근하여 빠름 (O(1)) |
func solution(_ clothes: [[String]]) -> Int {
return clothes
.reduce(into: [:]) { $0[$1[1], default: 0] += 1 } // 의상 분류
.values
.map { $0 + 1 } // 해당 종류를 입지 않은 경우의 수 +1
.reduce(1, *) - 1 // (모든 경우의 수) - 1(아무것도 입지 않은 경우의 수)
}
💡 문제 출처
https://school.programmers.co.kr/learn/courses/30/lessons/42578