본문 바로가기
코딩 테스트

[Python] 코딩테스트 고득점Kit | 해시4-베스트앨범 cmp_to_key 정렬

by 카프리썬 2021. 8. 4.
728x90

아래의 문제는 프로그래머스 코딩테스트 고득점 Kit 내용이며 코드는 직접 푼 내용입니다.


베스트앨범

문제상황

 

요구사항

노래의 장르를 나타내는 문자열 배열 genres와 노래별 재생 횟수를 나타내는 정수 배열 plays가 주어질 때, 베스트 앨범에 들어갈 노래의 고유 번호를 순서대로 return 하도록 solution 함수를 완성하세요.

 

한사항

  • genres[i]는 고유번호가 i인 노래의 장르입니다.
  • plays[i]는 고유번호가 i인 노래가 재생된 횟수입니다.
  • genres와 plays의 길이는 같으며, 이는 1 이상 10,000 이하입니다.
  • 장르 종류는 100개 미만입니다.
  • 장르에 속한 곡이 하나라면, 하나의 곡만 선택합니다.
  • 모든 장르는 재생된 횟수가 다릅니다.

입출력


풀이과정

이전에 풀이방법과 거의 비슷한데 직접적인 sort정렬은 한번한다.

대신 cmp_to_key방식으로 한번더 정렬한다. 

 

첫번째 sort정렬은 속한 노래가 많이 재생된 장르순서를 기준으로 정렬한다.

두번째 정렬은 cmp_to_key 방식으로, 장르 내에서 많이 재생된 노래순서를 기준으로 정렬한다. 

 

cmp_to_key방식으로 정렬하는 함수를 1,-1,0으로 리턴하도록 정의하기가 좀 헷갈리긴 한데..

정렬기준이 여러개 있을경우 분기처리할 수 있다는 점은 좋을것 같다.

def compare(x,y):
    #x[0]:고유번호 x[1]:재생횟수
    if x[1] == y[1]: #장르내에서 재생횟수가 같다면
        if x[0] < y[0] : #정렬기준3.고유번호가 낮은노래순서로
            return -1 #고유번호가 작은값(x[0])을 앞으로 보낸다.
        else:
            return 1
    elif x[1] < y[1]: #장르내에서 재생횟수가 같지않을땐
        return 1 #정렬기준2.장르 내에서 많이 재생된 노래순서
    else:
        return -1

 

그리고 최종적으로 졍렬된 리스트중에서 두개씩 모은 베스트앨범 고유번호순서를 answer로 리턴한다. 

 

결과

from functools import cmp_to_key

def compare(x,y):
    #x[0]:고유번호 x[1]:재생횟수
    if x[1] == y[1]: #장르내에서 재생횟수가 같다면
        if x[0] < y[0] : #정렬기준3.고유번호가 낮은노래순서로
            return -1 #고유번호가 작은값(x[0])을 앞으로 보낸다.
        else:
            return 1
    elif x[1] < y[1]: #장르내에서 재생횟수가 같지않을땐
        return 1 #정렬기준2.장르 내에서 많이 재생된 노래순서
    else:
        return -1

def solution(genres, plays):
    answer=[]
    score={}
    index={}

    for i,(genre,play) in enumerate(zip(genres,plays)):
        if genre not in score.keys():
            score[genre]=play
            index[genre]=[[i,play]]
        else:
            #print([i, play])
            score[genre]+=play
            index[genre].append([i, play])
    print(score) #{'classic': 1450, 'pop': 3100}
    print(index) #{'classic': [[0, 500], [2, 150], [3, 800]], 'pop': [[1, 600], [4, 2500]]}

    #정렬기준1.속한 노래가 많이 재생된 장르순서
    top_genre=sorted(score.items(),key=lambda x:x[1],reverse=True)
    print(top_genre) #[('pop', 3100), ('classic', 1450)]

    for genre in top_genre:
        sort_genre=genre[0]
        #정렬기준2.장르 내에서 많이 재생된 노래순서
        sort_music_list=sorted(index[sort_genre],key=cmp_to_key(compare))
        print(sort_music_list)

        #정답:두개씩 모은 베스트앨범 고유번호순서
        for best_music in sort_music_list[:2]:
            best_index = best_music[0]
            answer.append(best_index)
    return answer

genres=["classic", "pop", "classic", "classic", "pop"]
plays=[500, 600, 150, 800, 2500]
print(solution(genres, plays))

 

배운점 

 

 

 

 

반응형