[코드테스트] 실패율

이강민·2021년 11월 10일
0

[코드테스트]Javascript

목록 보기
17/39
post-thumbnail

실패율

문제설명

슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다. 원인은 신규 사용자와 기존 사용자 사이에 스테이지 차이가 너무 큰 것이 문제였다.

이 문제를 어떻게 할까 고민 한 그녀는 동적으로 게임 시간을 늘려서 난이도를 조절하기로 했다. 역시 슈퍼 개발자라 대부분의 로직은 쉽게 구현했지만, 실패율을 구하는 부분에서 위기에 빠지고 말았다. 오렐리를 위해 실패율을 구하는 코드를 완성하라.

  • 실패율은 다음과 같이 정의한다.
    • 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수

전체 스테이지의 개수 N, 게임을 이용하는 사용자가 현재 멈춰있는 스테이지의 번호가 담긴 배열 stages가 매개변수로 주어질 때, 실패율이 높은 스테이지부터 내림차순으로 스테이지의 번호가 담겨있는 배열을 return 하도록 solution 함수를 완성하라.

제한사항

  • 스테이지의 개수 N은 1 이상 500 이하의 자연수이다.
  • stages의 길이는 1 이상 200,000 이하이다.
  • stages에는 1 이상 N + 1 이하의 자연수가 담겨있다.
    • 각 자연수는 사용자가 현재 도전 중인 스테이지의 번호를 나타낸다.
    • 단, N + 1 은 마지막 스테이지(N 번째 스테이지) 까지 클리어 한 사용자를 나타낸다.
  • 만약 실패율이 같은 스테이지가 있다면 작은 번호의 스테이지가 먼저 오도록 하면 된다.
  • 스테이지에 도달한 유저가 없는 경우 해당 스테이지의 실패율은 0 으로 정의한다

입출력 예

N stages result
5 [2, 1, 2, 6, 2, 4, 3, 3] [3,4,2,1,5]
4 [4,4,4,4,4] [4,1,2,3]

입출력 예 #1
1번 스테이지에는 총 8명의 사용자가 도전했으며, 이 중 1명의 사용자가 아직 클리어하지 못했다. 따라서 1번 스테이지의 실패율은 다음과 같다.

  • 1 번 스테이지 실패율 : 1/8

2번 스테이지에는 총 7명의 사용자가 도전했으며, 이 중 3명의 사용자가 아직 클리어하지 못했다. 따라서 2번 스테이지의 실패율은 다음과 같다.

  • 2 번 스테이지 실패율 : 3/7

마찬가지로 나머지 스테이지의 실패율은 다음과 같다.

  • 3 번 스테이지 실패율 : 2/4
  • 4번 스테이지 실패율 : 1/2
  • 5번 스테이지 실패율 : 0/1

각 스테이지의 번호를 실패율의 내림차순으로 정렬하면 다음과 같다.

  • [3,4,2,1,5]

입출력 예 #2

모든 사용자가 마지막 스테이지에 있으므로 4번 스테이지의 실패율은 1이며 나머지 스테이지의 실패율은 0이다.

  • [4,1,2,3]

문제 풀이 1

let N = 5; 
let stages = [2, 1, 2, 6, 2, 4, 3, 3];
let result = [];
let result1 = [];

function solution(N, stages) {
    let stage_pass_per = [];
  // 편의상 오름차순으로 정렬하였다. 
   stages.sort((a,b) => a-b);
    // 각 배열의 실패율 
    let cnt = 0;
    for (let i = 1; i <= N; i++) {
        //cnt에 스테이지의 갯수를 담았다. 
        cnt = stages.filter(element => i === element).length;

	//실패율을 담았다. 
        stage_pass_per[i-1] = cnt / stages.length;
   //여기서부터 꼬인듯 하다...
        stages = stages.filter((item)=>item!==i)
    }
    // 실패율이 높은 순서
    for (let i = 0; i < stage_pass_per.length; i++) {
        result[i] = stage_pass_per[i];
        
    }
    result = result.sort((a,b)=>b-a)
  //여기까지 실패율을 담은 배열이 나온다. 
  //하지만 아래에서부터 문제가 나오는데 객체형태로 id를 만들려고 하는데 방법이 도무지 생각이 나지 않았다. 
    console.log(result)
    console.log(stage_pass_per)
  //첫번째 코드실험을 통과하기 위한 강제 실행
   for(let i = 0; i< stage_pass_per.length; i++){
      if(result[i-1] ===result[i]){
          result1[i] = stage_pass_per.lastIndexOf(result[i])+1
        }else{
            result1[i] = stage_pass_per.indexOf(result[i])+1
        }
    }
    console.log(result1);
}
solution(N, stages);
                                   

문제 풀이 2

본인이 이 문제를 잘 풀 수 없었던 이유는 다음과 같다.

  • push에 대한 이해의 부재(객체도 push하여 사용가능하여 객체로 배열에 push를 하고 싶으면 { id:index, value_name:value}의 형태로 push가 가능하였다.
  • sort에 대한 이해의 부재(sort를 정렬할 때 내림차순의 원리와 오름차순의 원리를 늦게 알았다.) 단지 sort()를 사용하면 올림차순으로 한다던가, sort((a,b)=>b-a)를 하면 내림차순을 한는 것만을 알아 응용성이 현저히 떨어졌다.
    잠시 sort()에 대해 정리하면 a,b는 배열에서 index의 순서라고 생각해도 된다.
    만약 a>b일 경우에 -1을 리턴하면 a,b순이 아닌 b,a 순으로 정렬해야 음수의 값으로 오름차순이 된다. 또한 a<b, 1을 리턴하면 b,a 순으로 정렬해야 양수의 값으로 오름차순 할 수 있다.
    내림차순은 위와 반대이다.
  • map에 대한 이해, map의 callback함수를 잘 활용해야 객체를 받아도 id를 배열로 리턴할 지 아니면 value를 배열로 리턴할 지 결정이 된다.
//실패율 = 머물러 있는 스테이지의 수 / 클리어한 스테이지의 수 
let N = 4; //스테이지의 수
let stages = [4,4,4,4,4];

//매개변수를 2개를 받는다. 스테이지의 수와 그 스테이지에 각 도달한 유저들의 배열을 받는다.

function solution(N, stages) {
    //스테이지에 남는 수를 담기위한 변수이다.
    let stayNum = 0;
    //실패율을 담기위한 변수이다. 
    let fail_rate=0;
    //유저들의 수를 담는 변수이다.
    let user = stages.length;
    //객체형태로 실패율과 index를 담기위한 변수이다.
    let arr = [];
    //스테이지 1부터 5까지 실패한 수 찾기
    for (let i = 1; i <= N; i++) {
        //머물러 있는 스테이지의 수
        stayNum = stages.filter((element)=> element === i).length;
        // console.log(stayNum)
        // console.log(user)
        //만약 해당 스테이지에 머무르는 유저가 없다면 실패율은 0이다. 
        if(stayNum === 0){
            fail_rate = 0;
            //그 외 스테이지에 머무르는 사람이 있을 경우에는 스테이지를 통과한 사람 수 / 총 유저수를 하여 실패율을 구한다.
        }else{
            fail_rate = stayNum / user;
        }
        //각 스테이지를 통과한 사람의 실패율을 구하고 통과를 한 인원을 구하기 위해 감소누적한다. 
        user -= stayNum;
        //고유 번호와 같이 움직여야 정렬이 완성된다. 
        //객체형태로 실패율을 담는다. i는 스테이지가 되고 rate는 실패율을 담는 객체를 만든다.... 
        //객체도 push가 되는 것을 알았다!
        arr.push({id : i, rate : fail_rate});
    }
    //console.log(arr)
    //실패율이 큰수부터 정렬(내림차순), 실패율이 같다면 오름 순으로 정렬
    arr.sort((a,b)=> {
        //이제 정렬를 하면 되는데 실패율이 큰수부터 정렬한다. 
        //a<b , -1 || a>b , 1 이면 오름차순으로 정렬한다. 내림차순은 그 반대. 
        if(a.rate > b.rate){
            //a가 b보다 클때 -1을 리턴한다. b, a순으로 정렬(내림차순)
            return -1;
            //a가 b보다 작을 때 1을 리턴한다. b, a순으로 정렬(내림차순)
        }else if(a.rate < b.rate){
            return 1; 
            //그 외는 같을 경우가 된다. 이때는 id를 비교하여 오름차순으로 정렬하자.
        }else{
            //같은 경우 id는 오름 차순 정렬(위에 참고)
            if(a.id > b.id){
                return 1;
            }else if(a.id < b.id){
                return -1;
            }            
        }
        
    });
    //map은 배열로 리턴한다. 따라서 arr의 map을 하여 id만을 배열로 리턴 시키면 된다~!
    return arr.map((element)=> element.id)
    
}
solution(N, stages)

될 때까지 하면 된다.

profile
AllTimeDevelop

0개의 댓글

관련 채용 정보