Lv.3 베스트앨범

·2022년 4월 3일
0

프로그래머스

목록 보기
9/18

문제 설명

자료 구조

  • arrangedSet
    • 타입 : 객체
    • 저장 데이터 : 입력된 정보를 정리한 객체
  • answer
    • 타입 : 배열
    • 저장 데이터 : arrangedSet을 총 재생횟수 기준으로 재정리한 배열

풀이 과정

나는 아래와 같은 정보를 구하고 싶다.

  • 각 장르의 총 재생 횟수
  • 각 장르마다 재생 횟수가 가장 높은 TOP 2의 index

각 장르와 재생횟수가 담긴 배열들은 길이가 동일하고 index가 이어져있는 관계다.
reduce를 이용해서 arrangedSet이란 이름의 객체를 만든다.

예)

genre = ["classic", "pop", "classic", "classic", "pop"]
plays = [500, 600, 150, 800, 2500]
arrangedSet = {
  classic: { sum: 1450, list: [[800, 3], [500, 0]] }
  pop: { sum: 2500, list: [[2500, 4],[600, 1]] }
}

이제 각 장르들 중에서 sum이 가장 높은 순서대로 list의 index만 출력하고 싶다.
따라서 Object.entries를 써서 sum을 기준으로 내림차순 정렬한 배열로 만들었다.

answer = [
  [ 'pop', { sum: 3100, list: [[2500, 4],[600, 1]] } ],
  [ 'classic', { sum: 1450, list: [[800, 3], [500, 0]]  } ]
]

이제 배열을 돌면서 각 요소들의 list의 index만 가져오면 된다.
단, 해당 장르의 곡이 하나만 있으면 두 번째 값을 못 읽는다.
그러므로 두 번째 index는 존재할 때에만 읽도록 처리한다.

코드 구현(JavaScript)

function solution(genres, plays) {
  const arrangedSet = genres.reduce((acc, cur, i) => {
    if (cur in acc) {
      acc[cur].sum += plays[i];
      acc[cur].list.push([plays[i], i]);
      acc[cur].list.sort((a, b) => b[0] - a[0]);
      acc[cur].list.length > 2 && acc[cur].list.pop();
    } else {
      acc[cur] = { sum: plays[i], list: [[plays[i], i]] };
    }
    return acc;
  }, {});

  let answer = Object.entries(arrangedSet).sort(([, a], [, b]) => b.sum - a.sum);
  answer = answer.reduce((acc, cur) => {
    acc.push(cur[1].list[0][1]);
    cur[1].list[1] && acc.push(cur[1].list[1][1]);
    return acc;
  }, []);

  return answer;
}

출처: 프로그래머스

profile
모르는 것 투성이

0개의 댓글