프로그래머스/알고리즘 고득점 Kit

[프로그래머스] [해시] Lv.3 /베스트앨범 (파이썬/Python)

junslee 2025. 3. 28. 10:37

1. 문제 설명

2. 풀이 과정 

장르별로 노래 정보를 저장하기 위해 genre_dict을 딕셔너리로 초기화하고 

genres와 plays를 zip()으로 묶어 enumerate()하면 i와 genre,play를 같이 저장할 수 있다.

genre가 genre_dict에 없으면 빈 리스트 []를 만들고 genre_dict[genre]에 i와 play를 저장한다.

장르별 노래 정보를 저장했으므로 총 재생 횟수를 계산해야 한다.

genre_dict의 genre와 songs를 items()로 불러와 songs에서 (고유번호, 재생횟수)형태로 무시 변수 _와 함께 play을 불러와 play의 합 sum()을 구한다.

genre_total 변수에 {genre: 총재생횟수}를 저장한다.

장르별로 총 재생횟수를 내림차순 정렬을 해야 한다.

sorted()함수로 genre_total을 정렬하는데 기준을 재생횟수로 해야 하므로 key=lambda x: genre_total[x]로 계산한다.

이제 결과를 넣을 result변수를 빈 리스트 []로 초기화한다.

sorted_genres에 genre를 불러와 장르별로 genre_dict[genre]를 정렬하는데 재생횟수로 내림차순 정렬해야 하고 같은 경우 장르 이름을 오름차순으로 정렬하면 된다.

result에 songs[:2]로 가장 재생 횟수가 많은 노래song의 고유번호만 extend()로 추가한다.

마지막에 result을 반환한다. 

3. 코드

def solution(genres, plays):
    genre_dict = {}
    for i, (genre, play) in enumerate(zip(genres,plays)):
        if genre not in genre_dict:
            genre_dict[genre] = []
        genre_dict[genre].append((i,play))
        
    genre_total = {genre: sum(play for _, play in songs) for genre, songs in genre_dict.items()}
    
    sorted_genres = sorted(genre_total, key=lambda x: genre_total[x], reverse = True)
    
    result = []
    for genre in sorted_genres:
        songs = sorted(genre_dict[genre], key=lambda x: (-x[1],x[0]))
        result.extend([song[0] for song in songs[:2]])
        
    return result

4. 추천 코드

def solution(genres, plays):
    answer = []
    d = {e:[] for e in set(genres)}
    for e in zip(genres, plays, range(len(plays))):
        d[e[0]].append([e[1] , e[2]])
    genreSort =sorted(list(d.keys()), key= lambda x: sum( map(lambda y: y[0],d[x])), reverse = True)
    for g in genreSort:
        temp = [e[1] for e in sorted(d[g],key= lambda x: (x[0], -x[1]), reverse = True)]
        answer += temp[:min(len(temp),2)]
    return answer

5. 추천 코드의 풀이 과정

장르별 노래 정보를 저장하기 위해 set(genres)로 장르 이름의 중복을 제거한다.

각 장르의 이름을 딕셔너리 키로 사용하여 저장한다.

노래 정보를 저장하기 위해 장르 이름, 재생횟수, 고유 번호를 동시에 순회하기 위해 zip()으로 묶는다.

각 장르에 속한 노래 정보를 딕셔너리에 저장한다.

장르별 총 재생 횟수로 정렬하기 위해

map(lambda y: y, d[x])로 각 키의 값을 sum()으로 합산하고 reverse = True로 내림차순 정렬한다.

장르 내에서 노래 재생 횟수가 많은 순으로 정렬하기 위해 key=lambda x : (x[0],-x[1])으로 정렬한다.

x[1]은 재생횟수로 내림차순 정렬하고, x[0]은 고유번호로 오름차순 정렬을 한다.

각 장르에서 두 개의 노래를 선택해 결과에 추가한다.

장르에 속한 노래가 하나라면 하나의 노래만 선택한다.