본문 바로가기
Developer/Algorithm

Programmers 2019 KAKAO BLIND RECRUITMENT - 실패율 (JavaScript)

by 김씩씩 2020. 9. 11.

Programmers 2019 KAKAO BLIND RECRUITMENT - 실패율 (JavaScript)

 

Programmers(프로그래머스)의 코딩테스트 연습문제 Level 1 중 2019 KAKAO BLIND RECRUITMENT 문제인 실패율 문제를 JavaScript를 사용하여 문제를 풀어보도록 하겠습니다.

 

문제 설명

출처 : Programmers 코딩테스트 연습 2019 KAKAO BLIND RECRUITMENT 키패드 누르기 문제 (https://programmers.co.kr/learn/courses/30/lessons/42889?language=javascript)

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

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

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

전체 스테이지의 개수 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]

 

 

작성한 답

solution.js

function solution(N, stages) {
    return Array.from({length:N}).map((v,i)=>{
        var a = stages.length;
        stages = stages.filter(v=>v>i+1);
        return {i:i+1, r:(a-stages.length)/a};
    }).sort((a,b)=>a.r==b.r ? a.i-b.i : b.r-a.r).map(v=>v.i);
}

 

설명

문제에서 설명해주는 그대로 하나씩 풀어나가면 정말 쉬운 문제입니다.

저는 정말 문제에서 설명하는 과정 그대로를 코드로 풀어내 보았습니다.

효율성 문제를 고려하지 않아 다른분들은 어떻게 풀었을지 모르겠지만 효율성이 조금 떨어지는 부분이 있는 것 같아 아쉽기는 합니다.

무튼 제가 해결한 방식을 설명 해드리도록 하겠습니다.

먼저 Array.from({length:N}) 함수를 사용해 스테이지 갯수이자 반환해야하는 배열의 길이인 N의 길이를 가지는 배열을 만들고,

map() 함수를 사용해 생성한 배열 안에 요소들을 채울 것입니다.

여기서부터 정말 너무나도 간단합니다.

먼저 게임을 이용하는 사용자가 현재 멈춰져있는 스테이지의 번호가 담긴 배열인 stages의 현재 길이를 먼저 변수 a에 담아놓습니다.

즉 a는 현재 스테이지에 도전했던 사람들의 수가 되는 것입니다.

그리고 stages를 현재 스테이지를 가리키는 i+1보다 큰 요소만을 filter()로 걸러줍니다.

즉, 현재 스테이지를 성공한 사람들만 배열에 남겨놓는 것이죠.

그럼 아까 변수 a에는 현재 스테이지에 도전했던 사람들의 수가 담겨있으므로,

(a-stages.length)/a 는,

(현재 스테이지에 도전했던 사람들의 수 - 현재 스테이지를 성공한 사람의 수) / (현재 스테이지에 도전했던 사람들의 수) = (현재 스테이지를 아직 클리어하지 못하고 다음 스테이지로 넘어가지 못한사람) / (현재 스테이지에 도전했던 사람들의 수) = 실패율 이 되는 것입니다.

실패율을 구했으니 이제 이 값을 object 형식으로 {i : (스테이지 넘버), r : (실패율) } 로 배열에 담아둡니다.

그렇게 모든 스테이지의 실패율을 구했으면 문제에서 요구하듯 실패율이 높은 스테이지부터 내림차순으로 만듭니다.

sort()함수를 사용하여 sort()함수 안의 인수 a,b를 사용해 먼저 실패율을 비교하고, 실패율이 높은 스테이지부터 내림차순으로 만들되, 실패율이 같으면 i를 비교하여 작은 번호의 스테이지가 먼저 오도록 합니다.

그렇게 내림차순으로 정렬이 완료되었으면 다시한번 map() 함수를 사용해 실패율은 지우고 내림차순으로 잘 정렬된 스테이지 넘버만을 남겨 return 해주면 문제가 해결됩니다!

 

 

제가 틀린 부분이 있다거나 더 좋은 방법을 아시는 분이 계시다면 댓글로 공유 부탁드립니다!

 

 

도움이 되셨다면 공감, 댓글 부탁드립니다!

궁금하신 점이나 요청 사항은 언제든지 말씀 해주세요!

 

감사합니다.


댓글