import java.util.*;
public class 실패율 {
public static void main(String[] args) {
int N = 5;
int N2 = 4;
int N3 = 2;
int N4 = 3;
int N5 = 7;
int[] stages = {2, 1, 2, 6, 2, 4, 3, 3};
int[] stages2 = {4, 4, 4, 4, 4};
int[] stages3 = {1, 1, 1, 1};
int[] stages4 = {1, 2, 2, 1, 3};
int[] stages5 = {2, 4, 4, 4, 4};
System.out.println(Arrays.toString(solution(N, stages)));
System.out.println(Arrays.toString(solution(N2, stages2)));
System.out.println(Arrays.toString(solution(N3, stages3)));
System.out.println(Arrays.toString(solution(N, stages4)));
System.out.println(Arrays.toString(solution(N4, stages5)));
}
public static int[] solution(int N, int[] stages) {
Map<Integer, Stage> stageMap = new HashMap<>();
for (int i = 1; i <= N + 1; i++) {
stageMap.put(i, new Stage(i, 0, 0));
}
Arrays.sort(stages);
// 게임의 게이머 수
int gamers = stages.length;
for (int i = 0; i < stages.length; i++) {
// N 이 5 라면 Stage 1 ~ 5 까지의 실패율만 가지고 결과를 리턴한다.
if (stages[i] > N) {
break;
}
int curStageCaseByUser = stages[i];
Stage stage = stageMap.get(curStageCaseByUser);
// 현재 유저의 스테이지가 배열의 다음 유저의 스테이지와 다른 경우, 스테이지의 실패합계를 증가 & 실패율을 최종 계산한다.
// 스테이지 맵에 업데이트 해준다.
// 최종 계산 후 게이머의 수 또한 해당 스테이지의 실패 합계로 빼준다.
if (i < stages.length - 1 && curStageCaseByUser != stages[i + 1]) {
stage.increaseFailSum();
stage.calculateFailRate(gamers);
stageMap.put(curStageCaseByUser, stage);
gamers -= stage.getFailSum();
// 현재 유저의 스테이지가 배열의 다음 유저의 스테이지와 같은 경우, 스테이지의 실패합계를 증가한다.
// 스테이지 맵에 업데이트 해준다.
// 게이머의 수는 배열이 정렬되어 있음으로 다음 유저의 스테이지와 같은 경우 감산을 하지 않는다.
} else if (i < stages.length - 1 && curStageCaseByUser == stages[i + 1]) {
stage.increaseFailSum();
stageMap.put(curStageCaseByUser, stage);
} else {
// stages 배열의 마지막 인덱스에 도달 해당 스테이지의 실패합계를 증가 & 실패율을 최종 계산한다.
// 스테이지 맵에 업데이트 해준다.
stage.increaseFailSum();
stage.calculateFailRate(gamers);
stageMap.put(curStageCaseByUser, stage);
}
}
return printSortedResult(N, stageMap);
}
private static int[] printSortedResult(int N, Map<Integer, Stage> stageMap) {
int[] answer = new int[N];
List<Map.Entry<Integer, Stage>> entryList = new ArrayList<>(stageMap.entrySet());
entryList.sort((e1, e2) -> Double.compare(e2.getValue().failRate, e1.getValue().failRate));
for (int i = 0; i < N; i++) {
answer[i] = entryList.get(i).getKey();
}
return answer;
}
public static class Stage {
private int stageNumber;
private int failSum;
private double failRate;
public Stage(int stageNumber, int failSum, double failRate) {
this.stageNumber = stageNumber;
this.failSum = failSum;
this.failRate = failRate;
}
public void increaseFailSum() {
this.failSum++;
}
public void calculateFailRate(int gamers) {
this.failRate = (double) this.failSum / gamers;
}
public int getFailSum() {
return this.failSum;
}
}
}
Leave a comment