개발/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
}