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.