[Level 2 / 조합] 메뉴 리뉴얼 + Swift

sanghee·2021년 10월 22일
0

🙈코딩테스트

목록 보기
38/52

문제 링크

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

입력

let orders = ["ABCFG", "AC", "CDE", "ACDE", "BCFG", "ACDEH"]
let course = [2, 3, 4]

출력

["AC", "ACDE", "BCFG", "CDE"]

풀이 내용

배열의 값을 활용해 딕셔너리 만들기

  1. map함수를 이용해 딕셔너리 안에 들어갈 값들을 만든다.
  2. 해당 값들로 딕셔너리를 만든다.
let course = [2, 3, 4]

let dictValues = course.map({ ($0, "value \($0)") })
print(dictValues)
// [(2, "value 2"), (3, "value 3"), (4, "value 4")]

let dict = Dictionary(uniqueKeysWithValues: dictValues)
print(dict)
// [2: "value 2", 3: "value 3", 4: "value 4"]

문자열로 문자열 배열 만들기

  1. 문자열을 문자열 배열로 만든다.
  2. 해당 배열의 각 요소의 타입은 Character이므로 map함수를 써서 String 타입으로 변환한다.

let order = "ABCFG"

let orderArr = Array(order).map({ String($0) })
print(orderArr) // ["A", "B", "C", "F", "G"]

문제 풀이

조합 함수

  1. 문자열 배열과 목표 숫자(길이)를 받는다.
  2. combinate 함수에서 index는 0, now은 ""로 시작한다.
  3. now의 길이가 목표 길이와 일치하는 경우에 result에 넣고 끝낸다.
  4. 그렇지 않은 경우에는 for문을 돈다.
func getCombination(_ array: [String], _ targetNum: Int) -> [String] {
    var result: [String] = []
    
    func combinate(_ index: Int, _ now: String) {
        if now.count == targetNum {
            result.append(now)
            return
        }
        for i in index..<array.count {
            combinate(i + 1, now + array[i])
        }
    }
    
    combinate(0, "")
    return result
}

solution 함수

  1. course의 배열의 값을 key로 가진 딕셔너리 dict을 생성한다.
  2. orders의 order를 잘라 배열로 만들어 정렬한다. 예로 order가 "ABCFG"인 경우 ["A", "B", "C", "F", "G"]로 생성한다.
  3. 해당 배열에서 course에 따라 2개를 선택한 조합 메뉴들, 3개를 선택한 조합 메뉴들, 4개를 선택한 조합 메뉴들을 만들고 dict에 넣으며 카운트한다.
func solution(_ orders:[String], _ course:[Int]) -> [String] {
    
    // dict = [2: [:], 3: [:], 4: [:]]
    var dict = Dictionary(uniqueKeysWithValues: course.map({ ($0, Dictionary<String, Int>()) }))

    for order in orders {
        let orderArr = Array(order).map({ String($0) }).sorted()
        
        for key in course {
            let combiArr = getCombination(orderArr, key)
            for menu in combiArr {
                if dict[key] != nil {
                    if dict[key]![menu] != nil {
                        dict[key]![menu]! += 1
                    } else {
                        dict[key]![menu] = 1
                    }
                }
            }
        }
    }

    ...
}
  1. course에 따라 2개일 때 조합 메뉴들 중 count가 가장 많은 메뉴들, 3개일 때..., 4개일 때... 를 구한 후에 해당 메뉴 key를 result에 넣는다.
  2. 알파벳 오름차순으로 정렬해 반환한다.
func solution(_ orders:[String], _ course:[Int]) -> [String] {
    ...

    var result: [String] = []
    
    for key in course {
        guard let maxValue = dict[key]?.values.max(), maxValue > 1 else { break }
        if let maxDict = dict[key]?.filter({ $0.value == maxValue }) {
            result.append(contentsOf: maxDict.keys)
        }
    }
 
    return result.sorted()
}

실행 결과

profile
👩‍💻

0개의 댓글