베스트앨범(프로그래머스)

정승옥(seungok)·2021년 2월 13일
0

프로그래머스

목록 보기
32/40
post-thumbnail

문제설명

  • 장르별 가장 많이 재생된 노래 2곡씩 모아 베스트 앨범 출시
  • 노래 수록 기준
    1) 가장 많이 재생된 장르를 먼저 수록
    2) 장르 내에서 가장 많이 재싱된 노래 먼저 수록
    3) 재생 횟수가 같을 경우 고유 번호가 낮은 노래를 먼저 수록
  • 장르를 나타내는 문자열 배열 genres
  • 재생횟수를 나타내는 정수 배열 plays

제한사항

  • genres[i], plays[i]인 노래는 고유번호가 i
  • 장르에 속한 곡이 1곡이면 1곡만 수록
  • 모든 장르는 재생된 횟수는 다름

풀이

function solution(genres, plays) {
    class MakeAlbum{
        constructor(){
            // 장르별 수록곡 정보를 담을 객체 listObj
            this.listObj = {};
        }
        // 인자로 정보를 받아 listObj에 장르별로 정보 추가
        checkPlayTime(genres, plays, index){
            if(this.listObj[genres]){
                this.listObj[genres].play += plays;
                this.listObj[genres].Serial.push([index,plays]);
            }
            else{
                this.listObj[genres] = {
                    genre: genres,
                    play: plays,
                    Serial: [[index,plays]]
                }
            }
        }
    }
    // 앨범 수록 노래들의 정보를 담을 객체 todayAlbum
    const todayAlbum = new MakeAlbum();
    genres.forEach((genre,index)=>{
        todayAlbum.checkPlayTime(genre,plays[index],index);
    })
    // 총 재생 횟수를 기준으로 내림차순 정렬 배열 ArrayAlbum
    const ArrayAlbum = [];
    for(const genre in todayAlbum.listObj){
        ArrayAlbum.push(todayAlbum.listObj[genre]);
    }
    ArrayAlbum.sort((a,b)=>b.play-a.play);
    const answer = [];
    for(let i=0;i<ArrayAlbum.length;i++){
        // 장르별 앨범 수록 횟수 pushTime
        // 장르별 배열 인덱스 index
        let pushTime = 0;
        let index = 0;
        // 인덱스 i인 장르의 곡들을 재생횟수로 내림차순 정렬
        ArrayAlbum[i].Serial.sort((a,b)=>b[1]-a[1]);
        for(let j=0;j<ArrayAlbum[i].Serial.length;j=index){
            const pointArr = ArrayAlbum[i].Serial;
            // 재생횟수가 같을 경우
            if(pointArr[j+1] && pointArr[j][1] === pointArr[j+1][1]){
                // 고유번호로 오름차순 정렬한 배열 filterSerial
                const filterSerial = pointArr
                            .filter(e=>e[1]===pointArr[j][1])
                            .sort((a,b)=>a[0]-b[0]);
                // 첫번째 인덱스의 고유번호를 앨범에 추가
                answer.push(filterSerial[0][0]);
                ++pushTime;
                // 해당 장르에서 2곡을 수록했을 경우 
                if(pushTime === 2){
                    // index는 재생횟수가 같은 곡들의 마지막 다음 곡의 인덱스
                    index += pointArr
                      .filter(e=>e[1]===pointArr[j][1])
                      .length;
                }
                else
                    ++index;
            }else{
                answer.push(pointArr[j][0]); 
                ++pushTime;
                ++index;
            }
            // 2곡을 수록했을 경우 빠져나옴
            if(pushTime === 2)
                break;
        }
    }
    return answer;
}

체크포인트

  • 배열형태 객체로 생성할 경우 장르가 pop 이면 배열 메소드로 호출되므로 주의
  • listObj 에 각 장르별로 총 재생횟수, 고유번호, 곡마다 재생횟수, 장르 정보를 담음
  • filter() 메소드로 필요한 곡들만 추출
  • sort() 메소드로 내림차순 또는 오름차순 정렬
  • 정렬 순서
    1) 장르별 총 재생횟수를 기준으로 내림차순 정렬
    2) 정렬된 각 장르에서 곡들을 재생횟수를 기준으로 내림차순 정렬
    3) 재생횟수가 같은 곡들만 추출해 오름차순 정렬
profile
Front-End Developer 😁

0개의 댓글