[프로그래머스] 실패율

ppyororong_0_0·2022년 1월 17일
0

프로그래머스

목록 보기
11/19

[프로그래머스 - 1단계] 실패율 문제

https://programmers.co.kr/learn/courses/30/lessons/42889

📝 문제 설명

실패율
= 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수

전체 스테이지의 개수 : N
현재 멈춰있는 스테이지 번호가 담긴 배열 : stages
실패율이 높은 스테이지부터 내림차순으로 스테이지 번호가 담긴 배열 return

  • N + 1 : 마지막 스테이지(N 번째 스테이지) 까지 클리어 한 사용자를 나타낸다.
  • 만약 실패율이 같은 스테이지가 있다면 작은 번호의 스테이지가 먼저 오도록 하면 된다.
  • 스테이지에 도달한 유저가 없는 경우 해당 스테이지의 실패율은 0 으로 정의한다.

💡 풀이

  1. failureRate 객체: 1~N까지의 숫자(스테이지)를 key로 갖고, 각각의 값은 0으로 초기화한다.
    각 단계 별 실패율을 나타내기 위해 failureRate객체를 만들어주었다.
    처음에는 0으로 초기화하였지만 추후, 단계별로 머물러있는 사람들 수를 구한 다음 실패율값을 넣어줄 것이다.

  2. stages 배열 순회 : failure[x]++해줌.
    ex) x가 2인 경우, 2를 key로 갖고 있는 failureRate객체의 값을 +1해준다.
    N + 1은 스테이지를 다 클리어했으니 제외하기 위해 조건을 설정해주었다.
    실패율을 구하기에 앞서, 단계별로 몇 명이 머물러 있는지 stages배열을 순회.

  3. 실패율 구하기

  • 해당 스테이지에 유저가 없으면 실패율은 0으로 설정하고,
    유저가 있으면 문제에 나온대로 실패율을 구한다.
  1. answer배열: 요소들이 [스테이지, 해당 스테이지의 실패율]로 이루어져 있다.

  2. answer배열 정렬: 실패율이 높은 순서대로 스테이지 정렬(내림차순), 실패율이 같은 것끼리는 스테이지 오름차순으로 정렬.

  3. 스테이지만 모아서 newArr에 넣은 후 답으로 return

🖥️ 코드

function solution(N, stages) {
    let answer = [];
    let failedCnt = 0;  // 스테이지를 올라가면서 클리어하지 못한 사용자 수를 누적
    const failureRate = {}; // 스테이지별 실패율을 표시하기 위한 객체 
    
    for (let i = 1; i <= N; i++) { // i는 key로 사용되며 스테이지를 나타낸다. 
        failureRate[i] = 0;       // 1단계부터 N단계까지 0으로 초기화한다.
    }
    
    for (let x of stages) {
        if (x < N + 1) failureRate[x]++; // 단계별로 현재 몇 명이 머물러 있는지 알기 위해 stages배열을 순회.
    }
    
    for (let i = 1; i <= Object.keys(failureRate).length; i++) {
        let tmp = failureRate[i];
        
        if (tmp === 0) failureRate[i] = 0; // 해당 스테이지에 유저가 없으면 실패율은 0
        else failureRate[i] = tmp / (stages.length - failedCnt); // 해당 스테이지에 유저가 있으면 실패율 공식에 맞게 실패율을 구함
        
        failedCnt += tmp; 
    }
    
    for (let key in failureRate) {
        answer.push([Number(key), failureRate[key]]);
    }
    answer.sort((a, b) => {
        if (a[1] === b[1]) return a[0] - b[0]; // 실패율이 같으면 key 오름차순 정렬
        else return b[1]-a[1]; // 그렇지 않으면 실패율이 높은 순서대로 내림차순 정렬
    } )
    
    let newArr = [];
    for (let i = 0; i < answer.length; i++) { 
        newArr.push(answer[i][0]); // 정렬한 스테이지 순서대로 newArr배열에 넣기(실패율은 말고 스테이지만) 
    }
    return newArr;
}

스테이지별 실패율을 구했는데 스테이지만 return하려니 따로 분리하는 방법을 생각해내는 게 어려웠다.


❗ 다른 사람 풀이

function solution(N, stages) {
    let stageRatio = [];
    let users = stages.length;
    
    for(let i = 1; i <= N; i++) {
        let noClear = stages.filter((user) => i === user).length;
        let ratio = noClear/users;
        users -= noClear;
        stageRatio.push({stage:i, ratio:ratio});
    }
    
    stageRatio.sort((a, b) => {
        if(a.ratio === b.ratio) return a.stage - b.stage;
        else return b.ratio - a.ratio;
    });
    
    return stageRatio.map(obj => obj.stage);
}

참고 사이트 바로가기

이해하기 쉽게 깔끔하게 코드를 잘 짜신 것 같다!
filter()함수로 각 단계별 클리어하지 못한 인원 수 구하는 방법이랑
객체의 프로퍼티를 stage, ratio 이렇게 따로 설정해주는 방법은 생각하지 못했는데 다른 사람 풀이 덕분에 알게 돼서 좋았다.

profile
안녕하세요!

0개의 댓글