문제풀이/구현

[Javascript/자바스크립트] (프로그래머스) 베스트앨범

딜레이레이 2025. 5. 8. 16:41

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

코드

function solution(genres, plays) {
  let answer = [];
  const genreCnt = new Map();
  for (let i = 0; i < genres.length; i++) {
    if (!genreCnt.has(genres[i])) {
      genreCnt.set(genres[i], 0);
    }
    genreCnt.set(genres[i], genreCnt.get(genres[i]) + plays[i]);
  }

  const sortedGenreCnt = Array.from(genreCnt.entries()).sort(
    (a, b) => b[1] - a[1]
  );

  for (const [genre, _] of sortedGenreCnt) {
    const sortedGenre = genres
      .reduce((acc, cur, idx) => {
        if (cur === genre) {
          acc.push([idx, plays[idx]]);
        }
        return acc;
      }, [])
      .sort((a, b) => b[1] - a[1]);

    answer.push(sortedGenre[0][0]);
    if (sortedGenre.length > 1) {
      answer.push(sortedGenre[1][0]);
    }
  }

  return answer;
}

 

이 문제의 풀이는 크게 2단계로 나눌 수 있다.

 

1. 장르에 속한 곡이 가장 많이 재생된 곡부터 내림차순 정렬하기

우선 각 장르에 속한 곡이 몇 번 플레이됐는지 구해야 한다. 장르와 플레이 횟수가 각기 다른 배열로 주어졌기 때문에 인덱스만을 이용해서 합산을 구한다. 합산은 key-value 형태로 값을 저장할 수 있는 Map 자료구조에 저장한다.

for (let i = 0; i < genres.length; i++) {
    if (!genreCnt.has(genres[i])) {
      genreCnt.set(genres[i], 0);
    }
    genreCnt.set(genres[i], genreCnt.get(genres[i]) + plays[i]);
}

그런 뒤에 이 합산을 내림차순 정렬하면 된다. 근데, Map 자료구조 자체는 정렬을 할 수 없기에 `entries()` 메서드로 [key, value] 형태의 원소를 가진 배열로 만들어서 정렬한다.

const sortedGenreCnt = Array.from(genreCnt.entries()).sort(
	(a, b) => b[1] - a[1]
);

 

2. 각 장르 내에서 가장 많이 재생된 노래 2곡 구하기

가장 많이 재생된 장르부터 해당 장르 내에서 가장 많이 재생된 노래 2곡을 구해서 answer에 추가하면 된다. 한 장르에서 가장 많이 재생된 노래 2곡을 찾는 과정은 다음과 같다.

const sortedGenre = genres
  .reduce((acc, cur, idx) => {
    if (cur === genre) {
      acc.push([idx, plays[idx]]);
    }
    return acc;
  }, [])
  .sort((a, b) => b[1] - a[1]);

answer.push(sortedGenre[0][0]);
if (sortedGenre.length > 1) {
  answer.push(sortedGenre[1][0]);
}

 

  2-1) `genres.reduce()`를 활용하여 현재 장르에 속한 곡들을 `[인덱스, 재생횟수]` 형태로 뽑아낸 뒤에 이를 재생횟수 내림차순으로 정렬한다. 이때 자바스크립트의 `sort()` 메서드는 안정적인 정렬 알고리즘(동일한 값을 가진 요소들의 순서가 변경되지 않음)을 사용하기 때문에 재생횟수가 같은 경우에는 인덱스(고유 번호)가 더 낮은 노래가 앞선 순서로 들어간다.

 

  2-2) `sortedGenre`에서 앞의 2곡의 고유 번호를 answer에 추가한다. 만약 장르 내에 노래가 한 곡뿐이라면 한 곡만 추가한다.