[프로그래머스/Swift] lv3 : 베스트앨범

문제

https://school.programmers.co.kr/learn/courses/30/lessons/42579

풀이

  • 중첩 dictionary 활용 [String:[Int:Int]]

  • 장르 : [인덱스:플레이횟수] 형태로 주어진 배열들의 값을 저장

  • 전체 플레이 횟수를 저장하는 dictionary를 선언하여, 이를 기준으로 key 정렬

  • 정렬된 Key를 loop를 통해 순회하며 순차적으로 return value에 알맞게 append

import Foundation

func solution(_ genres:[String], _ plays:[Int]) -> [Int] {
    // genres : [id:plays]
    var dict = [String:[Int:Int]]()
    // return value
    var rst = [Int]()

    // save total value
    var totals = [String:Int]()

    // i -> index
    // set dict
    for i in 0..<genres.count {
        let genre = genres[i]    
        if dict[genre] == nil {
            dict[genre] = [Int:Int]()
            dict[genre]![i] = plays[i]
        } else {
            dict[genre]![i] = plays[i]
        }
        // set totals
        if totals[genre] == nil {
            totals[genre] = plays[i]
        } else {
            totals[genre]! += plays[i]
        }
    }

    // 값이 큰 순서대로 key 가져오기
    for (k,_) in totals.sorted { $0.value > $1.value } {
        // 주의 : 값이 같은 경우 인덱스 번호가 작은 노래를 담아야함으로 두 번의 정렬을 실행함
           let tmp = dict[k]!.sorted { $0.key < $1.key }.sorted { $0.value > $1.value }
        // 노래가 두개 이상이 아니면 하나만 가져오기
        if tmp.count < 2 {
            rst.append(tmp[0].key)
        } else {
            rst.append(tmp[0].key)
            rst.append(tmp[1].key)
        }
    }

    return rst
}

후기

중첩 딕셔너리를 처음 사용해봤는데, 중간 단계마다 디버깅 과정을 거치지 않으면 에러가 발생하기 쉬울 것 같다. 다른 풀이들을 참고해보니 struct를 선언해서 활용하는 경우도 꽤 있는 것 같다. 좀 더 데이터가 정리돼서 나쁘지 않은듯. 다음엔 구조체를 만들어서 풀어봐야겠다.

처음 제출했을 때, 같은 값을 가지는 노래의 경우 인덱스 번호가 작은 노래를 담아야했는데 이를 문제에서 놓쳐서 실패했었다. 문제를 꼼꼼하게 잘 읽고 조건에 맞게 설계부터 한 뒤 문제 풀이를 시작하는 습관을 잘 들어야겠음