본문 바로가기
IT/알고리즘

프로그래머스 - 베스트 앨범 (파이썬, python)

by 시작은코딩 2025. 4. 6.
반응형

 

프로그래머스의 베스트 앨범을 파이썬으로 풀어보자!

 

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

꽤나 생각하기 어려운 문제다.

아래는 정답 코드.

def solution(genre_array, play_array):
    n = len(genre_array)
    genre_total_play_dict = {}
    genre_index_play_array_dict = {} # { "classic" : [index, playcount], ... }

    for i in range(n):
        genre = genre_array[i]
        play = play_array[i]

        if genre in genre_total_play_dict:
            genre_total_play_dict[genre] += play
            genre_index_play_array_dict[genre].append([i, play])
        else:
            genre_total_play_dict[genre] = play
            genre_index_play_array_dict[genre] = [[i, play]]

    sorted_genre_play_array = sorted(genre_total_play_dict.items(), key= lambda item: item[1], reverse=True )

    result = []

    for genre, total_play in sorted_genre_play_array:
        sorted_genre_index_play_array = sorted(genre_index_play_array_dict[genre], key=lambda item: item[1], reverse=True)

        genre_song_count = 0
        for index, play in sorted_genre_index_play_array:
            if genre_song_count >= 2:
                break
            result.append(index)
            genre_song_count += 1
    return result

 

🤓 요약

  • 장르별로 총 재생 수를 계산해서 인기 장르 순서를 정함
  • 각 장르 안에서 재생 수 높은 노래 2개를 고름
  • 고른 노래들의 인덱스만 리턴!

 

🧩 문제 상황 예시

예를 들어 이런 입력이 들어올 수 있다:

genre_array = ["classic", "pop", "classic", "classic", "pop"] 
play_array = [500, 600, 150, 800, 2500]
  • 0번 곡은 classic이고 500번 재생
  • 1번 곡은 pop이고 600번 재생
  • ...
  • 이런 식으로 되어 있다.

우리는 다음과 같은 기준으로 결과를 뽑아야한다:

  1. 장르 전체 재생 수를 기준으로 인기 순위를 매김.
  2. 각 장르에서 재생 수가 높은 노래 2개씩 선택.
  3. 그 노래의 인덱스만 리턴.

🔍 코드 단계별 설명

1. 데이터 저장용 딕셔너리 만들기

genre_total_play_dict = {} genre_index_play_array_dict = {}
  • genre_total_play_dict: 장르별 총 재생 수를 저장할 딕셔너리
  • genre_index_play_array_dict: 각 장르 안에서 [곡 인덱스, 재생 수] 리스트 저장

2. 장르별로 재생 수와 노래 정보 저장하기

for i in range(n): genre = genre_array[i] play = play_array[i]
  • 노래들을 하나씩 돌면서 장르와 재생 수를 꺼낸다.
 
    if genre in genre_total_play_dict:
        genre_total_play_dict[genre] += play
        genre_index_play_array_dict[genre].append([i, play])
    else:
        genre_total_play_dict[genre] = play
        genre_index_play_array_dict[genre] = [[i, play]]
  • 만약 이미 본 장르라면:
    • 총 재생 수에 더해주고
    • 해당 장르 노래 목록에 [인덱스, 재생 수] 추가
  • 처음 보는 장르라면:
    • 새로운 키로 추가하고 값을 넣어준다.

3. 장르 순위를 재생 수 기준으로 정렬

sorted_genre_play_array = sorted(genre_total_play_dict.items(), key= lambda item: item[1], reverse=True)
  • genre_total_play_dict에서 각 장르의 총 재생 수를 기준으로 내림차순 정렬
  • 이렇게 하면 재생 수가 많은 장르부터 순서대로 접근 가능하다.

4. 장르별로 상위 2개 노래 선택

for genre, total_play in sorted_genre_play_array:
    sorted_genre_index_play_array = sorted(genre_index_play_array_dict[genre], key=lambda item: item[1], reverse=True)
  • 각 장르 안에서 노래들을 재생 수 기준 내림차순 정렬
  • 즉, 해당 장르에서 가장 인기 많은 곡부터 앞으로 오게 돼
    genre_song_count = 0
    for index, play in sorted_genre_index_play_array:
        if genre_song_count >= 2:
            break
        result.append(index)
        genre_song_count += 1
  • 노래를 최대 2곡까지만 골라서 result에 인덱스만 추가
  • 2곡 뽑으면 break로 멈춰

5. 결과 반환

return result
  • 최종적으로 인기 있는 곡들의 인덱스를 담은 리스트를 반환.

🏁 예시

solution(["classic", "pop", "classic", "classic", "pop"], [500,600,150,800,2500])
  • classic 총 재생 수: 500 + 150 + 800 = 1450
  • pop 총 재생 수: 600 + 2500 = 3100
  • 순위: pop > classic

pop에서 인기 많은 순서대로 2곡 → 4, 1
classic에서 인기 많은 순서대로 3, 0

🟨 결과: [4, 1, 3, 0]


참고

sorted, lambda 는 뭘까?

sorted(genre_index_play_array_dict[genre], key=lambda item: item[1], reverse=True)

 

🔍 sorted() 함수란?

sorted(리스트, key=정렬기준, reverse=True/False)
  • 리스트를 새로운 정렬된 리스트로 만들어주는 함수야 (원본은 안 바뀜!)
  • key=를 사용하면 "어떤 값을 기준으로 정렬할지" 정할 수 있다.
  • reverse=True를 넣으면 내림차순 정렬.

🧪 key=lambda item: item[1] 이란?

이건 정렬 기준을 말함.

lambda item: item[1]
  • 이건 익명 함수(lambda 함수).
  • item은 리스트 안의 각 요소 하나.
  • 예를 들어 item = [3, 800]이면,
    • item[0]은 인덱스 (3)
    • item[1]은 재생 수 (800)
  • 즉, item[1]은 재생 수!

그래서 key=lambda item: item[1]는 👉 "재생 수를 기준으로 정렬해줘!" 라는 뜻.


🔁 전체를 정리하면

 

sorted_genre_index_play_array = sorted(
    genre_index_play_array_dict[genre],  # [[0, 500], [2, 150], [3, 800]]
    key=lambda item: item[1],            # item[1] → 재생 수 기준으로
    reverse=True                         # 큰 값부터 정렬 (내림차순)
)
🔽 실행 결과는:
[[3, 800], [0, 500], [2, 150]]

💡 참고: lambda 대신 def 함수 써도 돼

만약 lambda가 낯설면 이렇게도 가능:

def get_play(item):
    return item[1]

sorted_genre_index_play_array = sorted(genre_index_play_array_dict[genre], key=get_play, reverse=True)

결과는 같다.

반응형