반응형
프로그래머스의 베스트 앨범을 파이썬으로 풀어보자!
프로그래머스
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번 재생
- ...
- 이런 식으로 되어 있다.
우리는 다음과 같은 기준으로 결과를 뽑아야한다:
- 장르 전체 재생 수를 기준으로 인기 순위를 매김.
- 각 장르에서 재생 수가 높은 노래 2개씩 선택.
- 그 노래의 인덱스만 리턴.
🔍 코드 단계별 설명
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)
결과는 같다.
반응형
'IT > 알고리즘' 카테고리의 다른 글
백준 2675 문자열 반복 자바스크립트 Javascript (0) | 2022.04.21 |
---|---|
자바스크립트로 입출력 받기 (0) | 2022.04.18 |
백준 1316 그룹 단어 체커 파이썬 (0) | 2022.03.07 |
백준 2941 크로아티아 알파벳 (0) | 2022.03.03 |
백준 5622 다이얼 파이썬 (이해 안가는 부분 해결) (0) | 2022.03.02 |