프로그래머스 Level 1
🔒 실패율
슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다. 원인은 신규 사용자와 기존 사용자 사이에 스테이지 차이가 너무 큰 것이 문제였다.
이 문제를 어떻게 할까 고민 한 그녀는 동적으로 게임 시간을 늘려서 난이도를 조절하기로 했다. 역시 슈퍼 개발자라 대부분의 로직은 쉽게 구현했지만, 실패율을 구하는 부분에서 위기에 빠지고 말았다. 오렐리를 위해 실패율을 구하는 코드를 완성하라.
전체 스테이지의 개수 N, 게임을 이용하는 사용자가 현재 멈춰있는 스테이지의 번호가 담긴 배열 stages가 매개변수로 주어질 때, 실패율이 높은 스테이지부터 내림차순으로 스테이지의 번호가 담겨있는 배열을 return 하도록 solution 함수를 완성하라.
1
이상 500
이하의 자연수이다.1
이상 200,000
이하이다.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번 스테이지의 실패율은 다음과 같다.
2번 스테이지에는 총 7명의 사용자가 도전했으며, 이 중 3명의 사용자가 아직 클리어하지 못했다. 따라서 2번 스테이지의 실패율은 다음과 같다.
마찬가지로 나머지 스테이지의 실패율은 다음과 같다.
각 스테이지의 번호를 실패율의 내림차순으로 정렬하면 다음과 같다.
입출력 예 #2
모든 사용자가 마지막 스테이지에 있으므로 4번 스테이지의 실패율은 1이며 나머지 스테이지의 실패율은 0이다.
import java.util.*;
class Solution {
public int[] solution(int N, int[] stages) {
int[] answer = new int[N];
String[] rate = new String[N];
for(int i=1; i<=N; i++) {
float total = 0;
float fail = 0;
for(int s : stages) {
if(s >= i) total++;
if(s == i) fail++;
}
if(total == 0) rate[i-1] = "0.0" + Integer.toString(N-i);
else rate[i-1] = Float.toString(fail / total) + Integer.toString(N-i);
}
Arrays.sort(rate, Collections.reverseOrder());
for(int i=0; i<N; i++) {
answer[i] = N-Integer.parseInt(rate[i].substring(rate[i].length() -1 , rate[i].length()));
}
return answer;
}
}
1, 2, 15, 26, 27만 통과하고 나머지는 실패한 코드...
<문자열 내 마음대로 정렬하기>에서 다른 사람의 코드를 참고해서 실패율 뒤에 스테이지 번호를 역순으로 붙힌 후 내림차순으로 정렬한 다음 마지막 스테이지 부분만 추출하는 코드였다.
근데 어디서부터 어떻게 고쳐야할지 감도 안잡히는...
그래서 초기화 했다...
초심으로 돌아가서 하자...😂
import java.util.*;
class Solution {
public int[] solution(int N, int[] stages) {
int[] answer = new int[N];
HashMap<Integer, Float> s_rate = new HashMap<Integer, Float>();
String[] rate = new String[N];
for(int i=1; i<=N; i++) {
float total = 0;
float fail = 0;
float failure = 0;
for(int s : stages) {
if(s >= i) total++;
if(s == i) fail++;
}
if(total != 0) failure = fail/total;
s_rate.put(i, failure);
rate[i-1] = Float.toString(failure);
}
Arrays.sort(rate, Collections.reverseOrder());
int index = 0;
for(String r : rate) {
for(int i=1; i<=N; i++) {
if(Float.parseFloat(r) == s_rate.get(i)) {
answer[index] = i;
s_rate.replace(i, (float)-1.0);
index++;
break;
}
}
}
return answer;
}
}
이번에는 <문자열 내 마음대로 정렬하기>에서 감자가 작성한 코드를 참고해서 다시 풀었다.
map으로 실패율과 스테이지를 같이 저장하여 정렬 후 스테이지를 찾는 방식이였다.
실패가 현저히 줄어들긴 했지만 아직 3, 10, 11, 13, 17, 22, 23, 24가 남은 상태...
테스트 케이스 다 공개해줬으면 좋겠다ㅠ
import java.util.*;
class Solution {
public class game {
int stage;
double fail;
public game(int s, double f) {
this.stage = s;
this.fail = f;
}
}
public int[] solution(int N, int[] stages) {
int[] answer = new int[N];
List<game> games = new ArrayList<game>();
for(int i=1; i<=N; i++) {
double total = 0;
double fail = 0;
for(int s : stages) {
if(s >= i) total++;
if(s == i) fail++;
}
if(total != 0) games.add(new game(i, fail/total));
else games.add(new game(i, 0));
}
Collections.sort(games, (g1, g2) -> Double.compare(g2.fail, g1.fail));
for(int i=0; i<N; i++) {
answer[i] = games.get(i).stage;
}
return answer;
}
}
뭔가 하면서도 불안해서 "이것도 안되겠네ㅋ" 하면서 작성한 코드가...
뜻밖의 5점짜리 코드였다...
"이번엔 ArrayList로 해볼까?!" 했는데 감자는 항상 ArrayList에 두개 이상의 필드를 넣을 때 클래스로 호출해왔기에 스테이지와 실패율을 저장하는 game
이라는 클래스를 만들었다.
생성자도 만들어주고
이전 코드와 대부분 비슷하다.
각 스테이지별 현재 단계에 머무는 사람의 수(fail
)와 스테이지에 도달한 사람의 수(total
)을 구한 후 total
이 0이라면 실패율을 0으로, 아니라면 실패율을 fail/total
로 해준 후 스테이지 번호와 함께 game
객체에 넣어 games
에 넣어줬다.
대망의 정렬...
이거땜에 오래걸렸다..
처음에는 이 사이트를 보고
Arrays.sort(games, Comparator.comparingDouble(o1 -> o1.fail));
라고 적었는데
이런 오류가 떴다.
Arrays
에는 저런 메소드가 없다는 것 같아서
Collection
으로 바꿔주니
실패율이 내림차순...
그렇다고 뒤에 Collections.reverseOrder()
를 붙혀줘도 오류가 난다.
어떻게 역순으로 정렬할 수 있을까? 고민하다가 이 사이트를 보고 lambda로 내림차순 정렬이 가능하다는 것을 알았다.
Collections.sort(games, (g1, g2) -> Double.compare(g2.fail, g1.fail));
내림차순 정렬이라서 g1.fail
보다 g2.fail
을 먼저 써준다.
원래대로 오름차순으로 정렬했다면 (g1, g2)
순으로 정렬되었을 요소들을 Comparator를 이용해 g2
가 더 커야 참이 되어 내림차순으로 정렬할 수 있다.
Double.class에서 compare(double d1, double d2) 메소드
- d1 > d2이면 1 반환
- d2 < d1이면 -1 반환
- d1 = d2이면 0 반환
그리고games
의 요소를 순차적으로 answer
에 넣어주면 끝!!
📑 참고 사이트
그래서 앞의 코드들은 왜 안된 것일까...??
테스트 케이스를 볼 수 있다면 좋겠다ㅠㅠ