알고리즘 스터디

[프로그래머스] 해시 4. 베스트 앨범


풀이

 

먼저 딕셔너리에 키를 장르, 값을 {고유번호: 횟수}로 넣는다.

아래와 같이 장르별 횟수를 sum에 저장한다.

 

[('pop', {4: 2500, 1: 600, 'sum': 3100}), ('classic', {3: 800, 0: 500, 2: 150, 'sum': 1450})]

 

장르별 두 개의 고유번호를 정답배열에 추가한다.

 

원래 sum은 딕셔너리에 추가하고 싶지 않았는데 파이썬 사용이 미숙해 되는대로 하다보니 넣게 되었다.

def solution(genres, plays):
    answer = []
    dics = {}
    
    for i, g in enumerate(genres):
        if g not in dics.keys():
            dics[g] = {}
        dics[g][i] = plays[i]
   
    sorted_dic = {}
    for d in dics.items():
        sorted_dic[d[0]] = dict(sorted(d[1].items(), reverse=True, key=lambda item: item[1]))
        sorted_dic[d[0]]['sum'] = sum(d[1].values())
    
    sorted_dic = sorted(sorted_dic.items(), reverse=True, key=lambda item: item[1]['sum'])
    
    for g, d in sorted_dic:
        num = 0
        for i in d:
            answer.append(i)
            num += 1;
            if num == 2:
                break;

    return answer

 

앗.. 전체 합 구하려고 sum 추가해놓은거 까먹었다.

def solution(genres, plays):
    answer = []
    dics = {}
    
    for i, g in enumerate(genres):
        if g not in dics.keys():
            dics[g] = {}
        dics[g][i] = plays[i]
   
    sorted_dic = {}
    for d in dics.items():
    	# value 내림차순, 그 중에선 key로 오름차순 정렬
        sorted_dic[d[0]] = dict(sorted(d[1].items(), key=lambda item: (-item[1], item[0])))
        sorted_dic[d[0]]['sum'] = sum(d[1].values())
    
    # sum 기준으로 내림차순 정렬
    sorted_dic = sorted(sorted_dic.items(), reverse=True, key=lambda item: item[1]['sum'])
    
    for g, d in sorted_dic:
        num = 0
        for i, v in d.items():
            if not i == 'sum':
                answer.append(i)
                num += 1;
                if num == 2:
                    break;
            
    return answer

레벨 3치고는 쉬웠는데 파이썬 다루는게 익숙치ㅣ 않아 오래 헤맸다.

 


몰랐던 문법

sorted_dic[d[0]] = dict(sorted(d[1].items(), key=lambda item: (-item[1], item[0])))

sort

- sorted를 사용하면 튜플 리스트로 반환된다. dict로 감싸줘서 딕셔너리로 반환시켰다.

- (-item[1]) 이런 식을 사용하면 내림차순, 오름차순을 섞어 정렬할 수 있다.

 


다른 사람 코드

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

 

# set으로 genres의 중복을 제거하고 key는 장르, value는 리스트인 딕셔너리 생성
# 예) {"classic": [], "pop": []}
d = {e:[] for e in set(genres)}
# zip을 사용해서 순회 
# 예) e = ("classic", 500, 0)
for e in zip(genres, plays, range(len(plays))):
    # 예) d["classic"] = ["500", 0]
    d[e[0]].append([e[1] , e[2]])

# 현재 자료형 예시
# d = { "classic": [[500, 0], [700, 1]], "pop": [[2500, 3], [100, 2]] } 

# 가장 많이 들은 장르 내림차순 정렬
genreSort =sorted(list(d.keys()), key= lambda x: sum( map(lambda y: y[0],d[x])), reverse = True)
# 정렬된 장르별 순회
for g in genreSort:
    # 1. 들은 수 내림차순, 2. 고유 번호 오름차순 정렬
    temp = [e[1] for e in sorted(d[g],key= lambda x: (x[0], -x[1]), reverse = True)]
    # 최대 두 개씩 추가
    answer += temp[:min(len(temp),2)]

 

 

dailyheumsi.tistory.com/67

cbw1030.tistory.com/229

leti-le.tistory.com/12

rfriend.tistory.com/473