내가 시작하자 하고 일주일만에 첫 문제 품. 이래서 한 달 안에 여섯 문제 풀려나;
알고리즘 초짠데 자꾸 시작하고 다시 엎어져서 화남. 망할 그래프에서 너무 오래 머무르지말고 이번 달은 Hash만 집중적으로 볼 예정이다.
자세한 문제 설명은 여기로
https://programmers.co.kr/learn/courses/30/lessons/42579
코딩테스트 연습 - 베스트앨범
스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다. 속한 노래가
programmers.co.kr
내 풀이
는 스터디 레포에 있다. 너무 무식하게 밀어붙인 것 같아서 짜증난다.
오늘의 깨달음
enumerate
vs. zip(lst, range(len(lst))
일단 죽어도 enumerate
쓰지 말라는건 기억해놓고 귀찮아서 써버림. 애초에 문제에서 고유번호를 요구했기 때문에 인덱스를 안 가져갈 수는 없었는데 제출하고 보니 다른 사람들 풀이에도 좋은 게 많았다.
sorted
- key를 잘 활용하자
정렬 기준이 원소의 합일 때
마지막에 총 플레이된 횟수를 기반으로 노래를 골라와야하는데 여기서 무식하게 순회하는 동안 계속 총 플레이 횟수를 더해왔다. 그러지 말고 마지막에 어차피 정렬을 한다면 key=lambda: ~
자리에 sum
으로 내가 원하는 값을 따로 구하는 게 메모리상 효율적인 것으로!
동일 값의 경우 우선순위 정해주기
감명 깊게 봤던 풀이인데
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
마지막에서 세 번째 줄에서 key 정렬이다. lambda x: (x[0], -x[1])
로 정렬했는데 이게 무슨 뜻이냐면 x[0]으로 먼저 정렬하고 그 값이 동일하면 x[1]로 정렬하는 것이다. 여기서 x[0]은 큰 순서고 x[1]은 작은 순서 정렬이라 여기에 음수를 취해서 원하는 대로 정렬을 해줬다. 진짜 갈 길이 멀구나!
난 애초에 2개씩 가지고 있기 싫어서 처음 부터 Hash맵에 넣을 때 상위 2개만 남겨놨었다. 아 이렇게 계산하니까 내가 총 플레이 횟수를 보관해야했구나! 내가 잘못한 게 아니었군. 이거 안 썼으면 혼자 난 멍청해 흑흑 하고 있었을 듯...
한 자료형에 대해 class
로 밀어버리기
Album
이라는 자료형을 만들어서 풀이한 사람이 있다. 이 문제에서 킹받는 포인트 중 하나는 한 번에 가지고 있어야할 정보가 너무 많다는 점인데 (장르, 플레이 횟수, 고유번호) 이걸 하나의 class
로 만들고 여기에 비교연산자를 플레이 횟수 기반으로 정리할 수 있게 해놓았다. 비교연산자 (operator
검색해보기)를 모두 만들어주면 장점은 sorted
같은 내장함수들도 모두 사용할 수 있다. 풀이 자체가 너무 직관적이라 좋았다.
dict
메소드 정확하게 알기
맨날 연구만 하면 메소드가 정확하게 어떤 자료형을 반환하는지 궁금해지지 않는다. 진짜 dict.get
은 없으면 None
반환한다는 것 잊지말자. 그리고 거기에 숫자를 계속 더해줘야 하는 상황이면 (+=
를 쓰고 싶으면) .get(없는 key, 0)
을 넣어주자.
분명히 예전에도 문제 풀고 나면 풀이를 보면서 공부한 것 같은데 이번에 유독 더 공부가 많이 되는 것 같다. 그동안은 코딩을 너무 못해서 그런 것인가...