코딩테스트

[코테] 프로그래머스 해시 알고리즘 - 베스트앨범 (문제풀이)

인어공쭈 2024. 5. 3. 18:21
문제설명)
스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 
노래의 장르를 나타내는 문자열 배열 genres와 노래별 재생 횟수를 나타내는 정수 배열 plays가 주어질 때, 베스트 앨범에 들어갈 노래의 고유 번호를 순서대로 return 하도록 solution 함수를 완성하세요.

 

 

문제풀이)
항상 그렇듯이 맵을 생성해서 장르를 저장한다. 하지만 이번엔 총 카운트가 필요해서 두개를 생성해서 담았다.
그다음에 총 카운트를 해서 제일 많은 카운트의 장르순으로 정렬을 한다 .
정렬을 한 다음 다시 순서대로 담으면 완성
function solution(genres, plays) {
    var answer = [];
    const genreMap = new Map();
    const genrePlayCount = new Map();
    
    for (let i = 0; i < genres.length; i++) {
        let genre = genres[i];
        let play = plays[i];
        if (!genreMap.has(genre)) {
            genreMap.set(genre, []);
        }
        genreMap.get(genre).push({ id: i, play: play });
        if (!genrePlayCount.has(genre)) {
            genrePlayCount.set(genre, 0);
        }
        genrePlayCount.set(genre, genrePlayCount.get(genre) + play);
    }
    
    const sortedGenres = Array.from(genrePlayCount.entries());
    sortedGenres.sort((a, b) => b[1] - a[1]);   
      for (const genre of sortedGenres) {
        const songs = genreMap.get(genre[0]);
        songs.sort((a, b) => b.play - a.play);
          console.log(songs,'songs')
        for (let i = 0; i < Math.min(2, songs.length); i++) {
            answer.push(songs[i].id);
        }
    }
    
    
    return answer;
}

 

 

그런데 뭔가 길고 복잡한 느낌이 들어서 리팩토링을 해봤다.

 

function solution(genres, plays) {
    const genreData = {};

    for (let i = 0; i < genres.length; i++) {
        const genre = genres[i];
        const play = plays[i];
        if (!genreData[genre]) {
            genreData[genre] = { songs: [], totalPlays: 0 };
        }

        genreData[genre].songs.push({ id: i, play });
        genreData[genre].totalPlays += play;
    }

    const sortedGenres = Object.entries(genreData).sort(
        ([, a], [, b]) => b.totalPlays - a.totalPlays
    );

    const answer = [];

    for (const [genre, data] of sortedGenres) {
        const { songs } = data;
        songs.sort((a, b) => b.play - a.play || a.id - b.id); 
        for (let i = 0; i < Math.min(2, songs.length); i++) {
            answer.push(songs[i].id);
        }
    }

    return answer;
}

 

하나의 맵으로 합쳐서 이게 좀더 깔끔한거 같지만 가독성이 내기준에선 떨어지는거 같아서 첫번째 풀이가 좀더 나은듯?

반응형