본문 바로가기

Algorithm

[프로그래머스 LV.3] 베스트앨범

오래간만에 코딩테스트 문제를 한번 풀어보았다.

 

알고리즘 문제인데 해시는 그나마 풀만할 것 같아서 도전해보았는데,,, 

역시 쥐약이다

 

하여튼 풀어냈는데 코드가 너무 더러운 것 같다,, 날 잡고 더욱 쉽고 깔끔하게 풀어낼 수 있도록 노력 해봐야겠다.

 

문제

 

딱봐도 dictionary 문제인 것 같다. 각 장르의 총합, 각 index 별 재생 횟수를 dictionary로 구분하여 저장해서 풀어야겠다 라는 생각부터 했다.

 

입출력 예

 

풀이

일단 각 장르의 총합, 장르의 idx와 재생 횟수를 추가하는 dictionary를 만들었다.

각 장르와 idx를 구분할 수 있도록 "/"를 넣어 'genre/idx' 를 key값으로, 재생횟수를 value로 넣었다.

이 부분을 따로 만들어버리지 않고 각 장르의 총합, 각 idx와 횟수를 튜플로 만든 값을 리스트에 담아 dictionary로 저장했으면 어떨까 라는 생각이 든다.

ex) ['classic' : [0000, [(0, 100), (0,200)]] 과 같이말이다.

* 추가로 genre_count는 각 장르 별 최대 2개만 담기 위해 구분할 수 있도록 추가해두었다. 사용 코드는 뒤쪽에 나온다.

 

각 장르별 총합과 genre/idx를 value값으로 sort하여 내림차순으로 정렬했다.

그 이유는 각 장르별 총합이 큰 것부터 2개씩 idx를 list에 담아 return 해야 하기 때문에 정렬해주었다.

 

각 장르별 상위 2개씩 잘라 담을 리스트이다.

이제 위에서 보았던 play_time을 사용하자. 내림차순으로 정렬된 play_time에서 각 장르별 2개씩 자르기 위해 각 genre별 genre_count를 += 1 하여 2가 넘으면 sort_play_time 리스트에 genre/idx를 담아준다.

 

그럼 각 장르별 상위 2개씩 잘라 담겨진 것을 확인할 수 있는데

 

완성된 리스트에서 가장 많이들은 genre 순으로 상위 2개씩 자른 것들의 idx를 담아 answer에 담아 return하면 된다.

이 때, 가장 많이 들은 genre와 상위 2개씩 잘라 담겨진 리스트의 genre와 맞으면 answer에 추가해 주는 로직을 사용해야 한다.

 

def solution(genres, plays):
    answer = []
    
    genre_play_time = {}
    play_time = {}
    play_num = {}
    genre_count = {}
    
    for idx, genre in enumerate(genres):
        genre_play_time[genre] = 0
        genre_count[genre] = 0
        play_time[genre + "/" + str(idx)] = 0
    
    for idx, genre in enumerate(genres):
        genre_play_time[genre] += plays[idx]
        play_time[genre + "/" + str(idx)] += plays[idx]
        
    genre_play_time = sorted(genre_play_time.items(), key = lambda item:item[1], reverse=True)
    play_time = sorted(play_time.items(), key= lambda item:item[1], reverse=True)
    sort_play_time = []
    
    for i in play_time:
        if genre_count[i[0].split("/")[0]] >= 2:
            continue
        sort_play_time.append(i)
        genre_count[i[0].split("/")[0]] += 1
    
    for i in genre_play_time:
        for j in sort_play_time:
            if i[0] in j[0].split("/"):
                answer.append(int(j[0].split("/")[1]))
    
    return answer

 

코드 진짜 더럽다.

더 깔끔하게 짜야겠다