실패율 (2019 KAKAO BLIND RECRUITMENT)
🔗 문제 링크
https://programmers.co.kr/learn/courses/30/lessons/42889
❔ 문제 설명
슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다. 원인은 신규 사용자와 기존 사용자 사이에 스테이지 차이가 너무 큰 것이 문제였다.
이 문제를 어떻게 할까 고민 한 그녀는 동적으로 게임 시간을 늘려서 난이도를 조절하기로 했다. 역시 슈퍼 개발자라 대부분의 로직은 쉽게 구현했지만, 실패율을 구하는 부분에서 위기에 빠지고 말았다. 오렐리를 위해 실패율을 구하는 코드를 완성하라.
실패율 = 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수
전체 스테이지의 개수 N, 게임을 이용하는 사용자가 현재 멈춰있는 스테이지의 번호가 담긴 배열 stages가 매개변수로 주어질 때, 실패율이 높은 스테이지부터 내림차순으로 스테이지의 번호가 담겨있는 배열을 return 하도록 solution 함수를 완성하라.
⚠️ 제한사항
-
스테이지의 개수 N은 1 이상 500 이하의 자연수이다.
-
stages의 길이는 1 이상 200,000 이하이다.
-
stages에는 1 이상 N + 1 이하의 자연수가 담겨있다.
-
각 자연수는 사용자가 현재 도전 중인 스테이지의 번호를 나타낸다.
-
단, N + 1 은 마지막 스테이지(N 번째 스테이지) 까지 클리어 한 사용자를 나타낸다.
-
만약 실패율이 같은 스테이지가 있다면 작은 번호의 스테이지가 먼저 오도록 하면 된다.
-
스테이지에 도달한 유저가 없는 경우 해당 스테이지의 실패율은 0 으로 정의한다.
💡 풀이 (언어 : Java & Python)
실패율 정렬하는데 필요한 기준이 두가지(실패율, 같을시 스테이지 숫자)이므로 따로 객체를 생성해서 두가지 기준을 받아주고 Comparator를 구현해서 정렬 기준으로 준다. 유저들의 스테이지 배열을 한번 돌아서 각 스테이지 별 유저들의 수를 기록해주고, 그 배열을 다시 돌면서 실패율을 계산해서 리스트에 넣어준다. 그 리스트를 객체와 Comparator를 이용해서 정렬해주고 실패율대로 정렬한 리스트의 원소의 스테이지 수로 정답 배열을 만들어주면 끝이다.
Java
public class Solution {
class FailInfo {
private int stage;
private double failRate;
private FailInfo(int stage, double failRate) {
this.stage = stage;
this.failRate = failRate;
}
}
public int[] solution(int N, int[] stages) {
int[] answer = new int[N];
// 총 실패율 계산 대상 유저 수
int total = stages.length;
// 모두 클리어한 유저로 인해 길이가 +1
int[] stageUser = new int[N+1];
// 각 스테이지 별 유저 수 배열 생성
for (int s : stages)
stageUser[s-1]++;
// 계산한 실패율을 스테이지별로 보관할 리스트 (인덱스 = 스테이지 숫자-1)
ArrayList<FailInfo> rateList = new ArrayList<>();
// 실패율 계산 (stageUser보다 인덱스 크기 1작은 N까지 - 모두 클리어한 사람은 배열 포함 x
for (int i = 0; i < N; i++) {
// 해당 스테이지의 유저 수가 0인 경우 실패율 0 처리
if (stageUser[i] == 0)
rateList.add(new FailInfo(i+1, 0));
else
rateList.add(new FailInfo(i+1, (double) stageUser[i]/total));
// 앞의 스테이지 도달한 사람 수를 전체 수에서 뺀 수가 다음 실패율 분모임
total -= stageUser[i];
}
// rateList를 정렬해주기
Collections.sort(rateList, new Comparator<FailInfo>() {
@Override
public int compare(FailInfo o1, FailInfo o2) {
if (o1.failRate < o2.failRate)
return 1;
else if (o1.failRate > o2.failRate)
return -1;
else {
if (o1.stage < o2.stage)
return -1;
// 여기서 스테이지 숫자가 같을리는 없다
else
return 1;
}
}
});
// 정답 배열 만들기
for (int i = 0; i < N; i++)
answer[i] = rateList.get(i).stage;
return answer;
}
}
Python
def solution(N, stages):
# 이미 계산한 숫자인지 체크
check = [True for i in range(N)]
answer = []
countList = []
for s in stages:
if s != N+1 and check[s-1]:
arriveList = list(filter(lambda x : x >= s, stages))
failList = list(filter(lambda x : x == s, stages))
failRate = len(failList) / len(arriveList)
countList.append((s , failRate))
check[s-1] = False
# 실패율이 높은 순으로 내림차순 정렬, 실패율 같으면 스테이지 숫자 오름차순 정렬
countList.sort(key = lambda x : (-x[1], x[0]))
for c in countList:
answer.append(c[0])
noNum = check.count(True)
for i in range(noNum):
idx = check.index(True)
answer.append(idx+1)
check[idx] = False
return answer
Author And Source
이 문제에 관하여(실패율 (2019 KAKAO BLIND RECRUITMENT)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@shiningcastle/실패율-2019-KAKAO-BLIND-RECRUITMENT저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)