알고리즘 문제풀이

[프로그래머스] 베스트 앨범 (Swift)

SiO2whocode 2024. 10. 15. 15:32
728x90

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

해시 Hash

 

N개의 노래에 대해 장르 배열 1개, 재생수 배열 1개가 주어지고

장르별로 2곡을 뽑아 하나의 앨범을 만들어야 함. > 앨범 트랙리스트 (배열 인덱스 = 노래의 고유번호)를 반환하는 문제

앨범에 수록 되는 노래 순서 중요

곡 선정 과정 1) 총합 재생수가 높은 장르의 곡 먼저 수록, 2) 재생수가 많은 곡 먼저 수록, 3) 재생수가 같을 경우 고유번호가 작은 순으로 수록

 

접근방법

Swift dictionary, tuple 사용, 정렬된 건 array에 담아서 사용

우선 [장르: 재생수 합] 딕셔너리를 만들고, [장르: [(노래 고유번호, 노래 재생수)]] 딕셔너리를 만들어서 풀이했다.

이후 map을 써서 장르를 재생수 순으로 정렬한 배열을 만들고 (genRank)

genRank로 반복문을 돌면서 장르별 두곡씩 수록하는 과정을 거쳤다.

이때 만들어둔 두번째 딕셔너리에서 해당 장르에 수록된 곡 배열을 1)재생수 순, 2) 번호순으로 정렬해서 고유번호만 뽑아낸다. (*해당 장르에 곡 수가 2개 이상인 경우만)

장르의 곡 수가 1개면 그대로 앨범에 수록한다. (정렬X - core dumped 남)

 

오답노트

- 배열의 원소가 한 개일 수 있는 경우에서 정렬을 하면 안됨(아마 커스텀 정렬함수를 사용해서 오류가 났던 것 같다. 빌트인이었으면 예외처리 해뒀겠지만)

- 그리고..Array append 할 때 여러개 원소를 한번에 추가할 경우 contentsOf로 전달해야함

 

 

소스코드

import Foundation

func solution(_ genres:[String], _ plays:[Int]) -> [Int] {
    var answer:[Int] = []
    
    var dict1:[String:Int] = [:]
    // 장르:재생수합
    
    var dict2 = [String:[(song: Int, plays: Int)]]()
    // 장르:노래 고유번호
        
    for (i, gen) in genres.enumerated() {
        if dict1[gen] == nil {
            dict1[gen] = plays[i]
        } else {
            dict1[gen]! += plays[i]
        }
        
        if dict2[gen] == nil {
            dict2[gen] = [(song: i, plays: plays[i])]
        } else {
            dict2[gen]!.append((song: i, plays: plays[i]))
        }
    }
    
    let genRank:[String] = dict1.sorted { $0.1 > $1.1 }.map{ $0.0 }
    
    for gen in genRank {
        var songs:[(song: Int, plays: Int)] = dict2[gen]!
        if songs.count >= 2 {
            var songs2 = songs.sorted { 
                if $0.1 == $1.1 {
                    return $0.0 < $1.0
                } else {
                    return $0.1 > $1.1
                }
            }.map{$0.0}
            answer.append(contentsOf:songs2[0...1])
        } else {
            answer.append(songs[0].song)
        }
    }
    
    return answer
}
728x90