이롭게 현명하게

[programmers - 42579] Lv3 베스트 앨범 / JavaScript 본문

알고리즘/programmers

[programmers - 42579] Lv3 베스트 앨범 / JavaScript

dev_y.h 2025. 10. 13. 18:00
728x90
반응형


문제

풀이

코드 설명

코드

후기


 

[programmers - 42579] Lv3 베스트 앨범 / JavaScript


[🔗문제🔗]

https://school.programmers.co.kr/learn/courses/30/lessons/42579

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

[programmers - 42579] Lv3 베스트 앨범 문제

 

 

[제한사항]

[programmers - 42579] Lv3 베스트 앨범 제한사항

[입출력 예시]

genres plays 출력
["classic", "pop", "classic", "classic", "pop"] [500, 600, 150, 800, 2500]   [4, 1, 3, 0]  

 


[풀이]

해시 알고리즘

 

여기서 장르별로 가장 많이 재생된 노래를 두 개씩 모아 앨범을 만든다.

스트리밍 genres 데이터
앨범 구성

 

장르별 총재생 횟수로 pop이 가장 많이 재생되었다.

장르별 총재생 횟수

 

앨범은 다음과 같이 구성되어 진다.

앨범 구성

 

pop에서 가장 많이 재생된 순서는 다음과 같다.

pop에서 가장 많이 재생된 순서

 

classic에서 가장 많이 재생된 순서는 다음과 같다.

classic에서 가장 많이 재생된 순서

 

장르별로 가장 많이 재생된 두 개만 앨범에 수록된다.

앨범은 다음과 같이 구성되어 완성된다.

완성된 앨범

 


[코드 설명]

딕셔너리로 장르별 총 재생 횟수, 고유번호 생성

for(let i=0;i<genres.length;i++){
        let type = genres[i]
        if(!dic[type]){ //딕셔너리에 키값(장르)이 없으면
            dic[type] = {sum:plays[i],plays:[{index:i, plays:plays[i]}]}
        }else{//딕셔너리에 키값(장르)이 있으면
            dic[type].sum+=plays[i]
            dic[type].plays.push({index:i, plays:plays[i]})
        }
    }

즉 출력하면 다음과 같은 결과가 나온다.

console.log(dic)

{
  classic: { sum: 1450, plays: [ [Object], [Object], [Object] ] },
  pop: { sum: 3100, plays: [ [Object], [Object] ] }
}

console.log(JSON.stringify(dic, null));
{
"classic":{
	"sum":1450,
	"plays":[
			{"index":0,"plays":500},
			{"index":2,"plays":150},
			{"index":3,"plays":800}
		]
	},
"pop":{
	"sum":3100,
	"plays":[
			{"index":1,"plays":600},
			{"index":4,"plays":2500}
		]
	}
}

[Object]가 나오는 이유는 자바스크립트 객체 안에 객체나 배열이 중첩되어 있을 때 기본적으로 [Object] 라고 표시하기 때문이다.

그래서 JSON.stringify로 보면 확인할 수 있다.

 

가장 많이 재생된 장르를 알아야 하기 때문에 장르별 총 재생 횟수를 정렬한다.

const sort = Object.keys(dic).sort((a, b) => dic[b].sum - dic[a].sum);
console.log(sort) // 	[ 'pop', 'classic' ]

각 장르의 상위 2곡만 answer에 추가한다.

playssort : 장르에 상위 2곡을 추출하기 위해 가장 많이 재생된 순으로 정렬한다.

slice로 자른 후 map으로 index(=노래 고유 번호) 만 추출한다.

...top : 펼쳐서 answer에 추가

 for(let genres of sort){
        const playssort = dic[genres].plays.sort((a, b) => b.plays - a.plays);
        const top = dic[genres].plays.slice(0,2).map(song => song.index);
        answer.push(...top);
}

 

 

<코드>

/*
1. 가장 많이 재생된 장르
2. 장르 내에서 많이 재생된 노래 수록
3. 장르 내에서 재생 횟수가 같은 노래는 고유 번호가 낮은 노래를 먼저 수록
4. 장르별로 가장 많이 재생된 노래를 최대 두개 까지 모은다.
*/

function solution(genres, plays) {
    var answer = [];
    var dic = {}
    
    // 딕셔너리로 장르별 총 재생 횟수, 고유번호 생성
    for(let i=0;i<genres.length;i++){
        let type = genres[i]
        if(!dic[type]){ //딕셔너리에 키값(장르)이 없으면
            dic[type] = {sum:plays[i],plays:[{index:i, plays:plays[i]}]}
        }else{//딕셔너리에 키값(장르)이 있으면
            dic[type].sum+=plays[i]
            dic[type].plays.push({index:i, plays:plays[i]})
        }
    }
    
    // 장르별 총 재생횟수 정렬
    const sort = Object.keys(dic).sort((a, b) => dic[b].sum - dic[a].sum);
    // console.log(JSON.stringify(dic, null));
    // console.log(sort)
    
    // 각 장르의 상위 2곡만 answer에 추가
    for(let genres of sort){
        const playssort = dic[genres].plays.sort((a, b) => b.plays - a.plays);
        // console.log(playssort)
        const top = dic[genres].plays.slice(0,2).map(song => song.index); //slice로 자른 후 index만 추출
        
        answer.push(...top); // 펼쳐서 answer에 추가
    }
    
    
// dic={ classic: 1450, pop: 3100 }   
//     for(let i=0;i<genres.length;i++){
//         const type = genres[i]
//         if(dic[type]){
//             dic[type]+=plays[i]
//         }else{
//             dic[type]=plays[i]
//         }
//     }

    
    return answer;
}

 


[후기]

이번 문제를 풀면서 이전에 풀었던 의상 문제(https://school.programmers.co.kr/learn/courses/30/lessons/42578)와 구조가 비슷하다고 생각되었다.

그래서 자연스럽게 딕셔너리를 활용해야겠다고 판단했다.

문제에서 요구하는 조건들을 만족시키기 위해 장르별 재생 횟수 합계와 각 노래 정보를 함께 저장하는 방식으로 딕셔너리를 설계했다.

문제를 단계적으로 해결하는 방법으로 접근하여 진행했다.

 


잘못된 정보는 댓글에 남겨주시면 감사하겠습니다!😊

댓글과 좋아요는 큰 힘이 됩니다!

728x90
반응형
Comments