ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Swift] 베스트앨범 프로그래머스 코딩테스트
    개발/Swift 2022. 1. 3. 18:41
    1. 속한 노래가 많이 재생된 장르를 먼저 수록합니다.
    2. 장르 내에서 많이 재생된 노래를 먼저 수록합니다.
    3. 장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록합니다.
    • 장르에 속한 곡이 하나라면, 하나의 곡만 선택합니다.
    • 모든 장르는 재생된 횟수가 다릅니다.

    우선 문제 해결을 위해

    1. 주어진 장르와 재생수를 가지고 dictionary로 만든후에
    2. 해당 dictionary를 총 재생수를 기준으로 정렬
    3. 장르 내 재생수 에 따른 정렬 (재생수 같으면 고유번호참조)
    4. 앞에서 두개 뽑아서 배열에 넣어서 리턴(갯수 1개면 1개만 넣어줌)

    우선 주어진값을 가지고 Dictionary를 만든다. 딕셔너리는 이런구조로 만들어 져야한다.

    ["classic": [2: 150, 0: 500, 3: 800], "pop": [5: 600, 4: 2500, 1: 600]]
    

    주어진 장르배열을 반복하면서 dictionary를 구현했다.

    key값(장르)가 nil이면 아직 key-value 내용이 없다는 뜻이므로

    재생횟수,고유번호를 가져와서 다시 딕셔너리를 만들어서 넣어주고

    nil 이 아니면 재생횟수,고유번호를 가져와서 기존값 에 넣어주면 된다.

    var dict = [String:Dictionary<Int, Int>]()
        var arr = [Int]()
        for (idx,item) in genres.enumerated() {
            if var playDict = dict[item] {
                playDict[idx] = plays[idx]
                dict[item] = playDict
            }else {
                var value = [idx:plays[idx]]
                dict[item] = value
            }
        }
    

    이제 이 딕셔너리를 정렬해야한다.

    정렬은 딕셔너리의 value값 (고유번호:재생횟수)의 value값(재생횟수) 들의 총합을 비교하여 정렬하면 된다.

    var sortedDict = dict.sorted { (first,second)  in
            let firstTotal = first.value.values.reduce(0) { total, play in
                return total + play
            }
            
            let secondTotal = second.value.values.reduce(0) { total, play in
                return total + play
            }
            
            return firstTotal > secondTotal
        }
    

    이제 이 정렬된 딕셔너리를 가지고 반복을 돌린후

    각각 value에서 재생횟수를 기준으로 정렬한다.

    for idx in 0..<sortedDict.count{
            let sortedPlayDict = sortedDict[idx].value.sorted { first, second in
                if(first.value == second.value){
                   return first.key < second.key
               }else{
                   return first.value > second.value
               }
            }
            print(sortedPlayDict)
       
        }
    

    위 의 sortedPlayDict 안에는 이런식으로 정렬이 완성된다.

    [(key: 4, value: 2500), (key: 1, value: 600), (key: 5, value: 600)]
    

    이제 반복문 안에서 sortedPlayDict 값 두개만 추출해서 배열에 넣어주면 된다. (1개면 1개만)

    if(sortedPlayDict.count < 2){
                arr.append(sortedPlayDict[0].key)
            }else {
                arr.append(sortedPlayDict[0].key)
                arr.append(sortedPlayDict[1].key)
            }
    

    전체 코드

    func solution(_ genres:[String], _ plays:[Int]) -> [Int] {
        var dict = [String:Dictionary<Int, Int>]()
        var arr = [Int]()
        for (idx,item) in genres.enumerated() {
            if var playDict = dict[item] {
                playDict[idx] = plays[idx]
                dict[item] = playDict
            }else {
                var value = [idx:plays[idx]]
                dict[item] = value
            }
        }
        
        var sortedDict = dict.sorted { (first,second)  in
            let firstTotal = first.value.values.reduce(0) { total, play in
                return total + play
            }
            
            let secondTotal = second.value.values.reduce(0) { total, play in
                return total + play
            }
            
            return firstTotal > secondTotal
        }
        
    
        for idx in 0..<sortedDict.count{
            let sortedPlayDict = sortedDict[idx].value.sorted { first, second in
                if(first.value == second.value){
                   return first.key < second.key
               }else{
                   return first.value > second.value
               }
            }
            if(sortedPlayDict.count < 2){
                arr.append(sortedPlayDict[0].key)
            }else {
                arr.append(sortedPlayDict[0].key)
                arr.append(sortedPlayDict[1].key)
            }
        }
        
        print(arr)
        return arr
    }
    

    댓글

Designed by Tistory.