Algorithm

[Javascript] 프로그래머스 - 베스트 앨범

합주기 2025. 1. 25. 14:23

🧾 목차

1. 문제 설명

2. 문제 풀이

3. 정답 코드


 

1. 문제 설명

장르별로 가장 많이 플레이된 노래를 2개씩 묶어 배스트 앨범을 만드는 문제입니다.

 

💡 이 때, 정렬 기준은 다음과 같습니다.

1) 총 플레이 수를 기준으로 장르를 정렬 (e.g. classic 과 pop의 총 플레이 수가 더 많은 게 더 먼저)

2)  각 장르당 플레이 수를 기준으로 곡 정렬 (e.g. classic의 곡은 총 3개이고, 그 곡들의 플레이 수를 기준으로 정렬)

 

입출력

 


2. 문제 풀이

1. 변수 선언

가장 고민을 많이 했던 부분이였습니다.

1) 총 플레이 수를 기준으로 정렬해야함
2) 곡 정보를 가지고 있어야 함 👉 [key: value] 를 [인덱스: 플레이 수]
3) 각 장르에서 플레이 수를 기준으로 정렬해야함

 

이 세가지를 염두에두고 객체 배열을 생성하였습니다.

 

2. 객체 배열에 저장

 

3. 정렬

정렬은 총 2회 진행했는데, 

첫번째는 총 플레이 수를 기준으로 내림차순 했고, 두번째는 각 장르에서 플레이 수를 기준으로 내림차순하였습니다.

 

4. 각 앨범당 최대 2곡 씩만 포함

 1) slice 배열 메소드를 활용하여 최대 2곡씩 슬라이스

 2) 그 곡들을 정답 배열에 추가


3. 정답 코드

function solution(genres, plays) {
  var answer = [];

  var genreObj = [];

  // 객체 배열에 저장
  // {장르: ?, 총 플레이 수: ?, 곡 정보 : [인덱스, 플레이 수]}
  for (let i = 0; i < genres.length; i++) {
    var genre = genres[i]; // 장르 이름
    var playcount = plays[i]; // 플레이 수

    var j = genreObj.findIndex((v) => v.genre == genre); // 현재 장르의 인덱스 찾기

    if (j >= 0) {
      genreObj[j].count += playcount; // 기존 장르의 플레이수 업데이트
      genreObj[j].plays.push([i, plays[i]]); // 곡 정보 업데이트
    } else {
      genreObj.push({ genre: genre, count: playcount, plays: [[i, plays[i]]] }); // 새로운 장르 추가
    }
  }

  // 총 카운트를 기준으로 내림차순
  genreObj.sort((a, b) => b.count - a.count);

  // plays의 플레이 수(2번째 인자)를 기준으로 내림차순
  genreObj.forEach((item) => {
    item.plays.sort((a, b) => b[1] - a[1]);
  });

  // 각 앨범당 최대 2곡 씩만 수록
  genreObj.forEach((item) => {
    item.plays.slice(0, 2).forEach((play) => {
      answer.push(play[0]); // 정답 배열에 인덱스 추가
    });
  });

  return answer;
}