반응형
안녕하세요. 개발 중인 정주입니다.
오늘은 "프로그래머스(Lv.2) - 메뉴 리뉴얼" 문제를 풀었습니다.
Github
문제 링크
풀이
이번 문제는 조합 구현 문제입니다.
order에 대해 만들 수 있는 모든 코스를 구한 후 가장 많이 주문한 것을 고르면 됩니다.
1. 코스 요리 개수 : [코스 종류] 배열을 생성합니다.
order에 대해 만들 수 있는 모든 코스 종류를 구합니다.
이때 XY와 YX는 같은 것으로 분류하므로 order를 사전순으로 정렬합니다.
2. 각 코스를 주문한 횟수를 구합니다.
해시 테이블을 이용해 각 코스를 주문한 횟수를 구합니다.
var orderCount: [String: Int] = [:]
courseRange.forEach { i in
for order in orderCombinations[i]! {
orderCount[order] = (orderCount[order] ?? 0) + 1
}
}
3. 요리 개수마다 가장 많이 주문한 횟수를 저장합니다.
가장 많이 주문한 요리를 구하기 위해 가장 많이 주문한 횟수를 저장합니다.
이렇게 구성한 이유는 매번 업데이트를 하는 방법을 그리 선호하지 않기 때문입니다. ㅠㅠ
4. 가장 많이 주문한 요리로만 코스를 구성합니다.
이때 가장 많이 주문했더라도 2회 미만이라면 코스에서 제외합니다.
가장 많이 주문한 요리로만 코스를 구성합니다.
5. 사전순으로 오름차순 정렬합니다.
사전순으로 오름차순 정렬합니다.
후기
다 풀고도 과정을 더 줄일 수 있을 것 같은데 확 떠오르지 않아 오래 걸린 문제였습니다.
사실 지금도 뭔가 더 줄일 수 있을 것 같은데 잘 모르겠네요...
조금 더 고민해봐야겠습니다.
감사합니다!
전체 코드
import Foundation
func makeOrder(_ string: [String], _ length: Int) -> [String] {
var order: [String] = []
func combination(_ index: Int, _ current: String) {
if current.count == length {
order.append(current)
return
} else {
for i in index..<string.count {
combination(i+1, current + String(string[i]))
}
}
}
combination(0, "")
return order
}
func solution(_ orders:[String], _ course:[Int]) -> [String] {
var result: [String] = []
let courseRange = (course.first!...course.last!) //가장 적은 개수 ~ 가장 많은 개수
//코스 요리 개수 : 코스 종류
var orderCombinations: [Int:[String]] = [:]
courseRange.forEach { orderCombinations[$0] = [] }
orders.forEach { order in
//주문 요리를 정렬합니다. XY, YX는 같은 코스
let orderArr = Array(order).sorted(by: <).map { String($0) }
courseRange.forEach {
//각 개수마다 만들 수 있는 코스 요리를 구한다.
let orderCombination = makeOrder(orderArr, $0)
for od in orderCombination {
orderCombinations[$0]?.append(od)
}
}
}
// print("orderCombinations: \(orderCombinations)")
//요리를 주문한 횟수를 구합니다.
var orderCount: [String: Int] = [:]
courseRange.forEach { i in
for order in orderCombinations[i]! {
orderCount[order] = (orderCount[order] ?? 0) + 1
}
}
// print("orderCount: \(orderCount)")
//각 요리 개수에 대해 가장 많이 주문한 횟수를 저장한다.
var maxCounts: [Int: Int] = [:]
courseRange.forEach { maxCounts[$0] = 0 }
orderCount.forEach {
maxCounts[$0.key.count] = max(maxCounts[$0.key.count]!, $0.value)
}
print("maxCounts: \(maxCounts)")
//2회 이상 주문한 요리 중 가장 많이 주문한 요리로만 코스를 구성한다.
for order in orderCount {
if course.contains(order.key.count) { //원하는 코스 요리 개수
if let maxCount = maxCounts[order.key.count], //가장 많이 주문한 횟수
order.value > 1, order.value == maxCount { //1회 이상, 가장 많이 주문한 요리면 append
result.append(order.key)
}
}
}
result.sort(by: <) //사전순으로 정렬
print("result: \(result)")
return result
}
아직은 초보 개발자입니다.
더 효율적인 코드 훈수 환영합니다!
공감과 댓글 부탁드립니다.
반응형