코딩테스트/프로그래머스

[프로그래머스] 메뉴 리뉴얼 (Swift)

도지대디 2022. 5. 29. 21:25

[프로그래머스] 메뉴 리뉴얼 (Swift)

https://programmers.co.kr/learn/courses/30/lessons/72411

 

코딩테스트 연습 - 메뉴 리뉴얼

레스토랑을 운영하던 스카피는 코로나19로 인한 불경기를 극복하고자 메뉴를 새로 구성하려고 고민하고 있습니다. 기존에는 단품으로만 제공하던 메뉴를 조합해서 코스요리 형태로 재구성해서

programmers.co.kr

풀이

Dictionary 의 특성들을 적극 활용해서 해결한 문제였습니다.

 

주문들을 주어진 길이만큼 조합하여 그 중 가장 빈도수가 많은 메뉴를 골라내는 문제입니다. 주의해야할 점은 메뉴도, 그리고 결과를 담은 배열도 모두 정렬되어있어야 한다는 점입니다.

 

일단 몇가지 메뉴를 조합해야하는지 숫자가 주어지기 때문에 이를 살펴봤습니다. 주어지는 배열 course 의 원소만큼 메뉴를 재조합해야 합니다.

 

이 때 주어지는 메뉴들을 담은 배열 orders 원소의 길이가 course 의 어떤 원소의 크기보다 작을 수 있다는 점을 생각해야 합니다.

예를 들어 orders"ABC" 라는 원소가 하나 있다고 하고, course 에 4 라는 값이 있다면 어떤 방식으로든 재조합이 불가능하기 때문에 해당 경우는 건너뛰는 것이 좋습니다.

 

결론적으로 orders 의 원소 길이가 course 의 원소 크기 이상인 경우에만 조합 메소드를 사용해주면 됩니다. 조합으로 인해 도출된 결과는 Dictionary 의 key 로 삼고, value 는 0부터 하나씩 증가시키며 등장 빈도를 저장합니다.

 

이후 모든 과정이 끝나면 course 의 각 개수마다 Dictionary 를 분리하여 가장 큰 value 를 찾고, 해당 value 를 가지는 key 들을 모아줬습니다.

 

마지막으로 모아둔 key 들을 정렬해주면 문제를 해결할 수 있습니다.

코드

func solution(_ orders: [String], _ courses: [Int]) -> [String] {
var answer: [String] = []
var temp: [String] = []
var dict: [[String]: Int] = [:]
// 조합 코드
func combinations(_ order: [String], _ count: Int, _ index: Int) {
if temp.count == count {
if let _ = dict[temp] {
dict[temp]! += 1
} else {
dict[temp] = 1
}
}
for i in index ..< order.count {
temp.append(order[i])
combinations(order, count, i + 1)
temp.removeLast()
}
}
// 주문 재조합
for order in orders {
let ord = order.sorted().map { String($0) }
for course in courses {
// order 길이가 course 보다 큰 경우에만
// 짧은 경우는 제외
if order.count > course {
combinations(ord, course, 0)
}
// 길이가 같으면 그냥 넣어도 됨
else if order.count == course {
if let _ = dict[ord] {
dict[ord]! += 1
} else {
dict[ord] = 1
}
}
}
}
// 최대 빈도수 가지는 메뉴 뽑기
for course in courses {
let newDict = dict.filter({ $0.key.count == course })
guard let maxValue = newDict.values.max() else {
break
}
let filtered = newDict.filter({ $0.value == maxValue && $0.value >= 2 }).map { $0.key.joined(separator: "") }
answer.append(contentsOf: filtered)
}
return answer.sorted()
}