송민준의 개발노트

프로그래머스-level1-실패율 본문

알고리즘/프로그래머스

프로그래머스-level1-실패율

송민준 2019. 11. 4. 23:39

https://programmers.co.kr/learn/courses/30/lessons/42889

 

코딩테스트 연습 - 실패율 | 프로그래머스

실패율 슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다. 원인은 신규 사용자와 기존 사용자 사이에 스테이지 차이가 너무 큰 것이 문제였다. 이 문제를 어떻게 할까 고민 한 그녀는 동적으로 게임 시간을 늘려서 난이도를 조절하기로 했다. 역시 슈퍼 개발자라 대부분의 로직은 쉽게 구현했지만, 실패율을 구하는 부분에서 위기에 빠지고 말았다. 오렐리를 위해 실패율을 구하는 코드를

programmers.co.kr

최초 코드(70점 정도 나옴)  => 1,6,7,9,13,23,24,25 테스트케이스 틀림

 

질문하기 게시판에 보니 나랑 비슷하게 틀린 사람들이 많았다.

 

원인은 즉슨 아래 제한사항을 고려를 안한 것이다....

또한 이것저것 시도를 해보다보니 필요없는 코드와 절차가 많았다.

(숫자 ÷ 0 이 있어서 그런지 계산도 먹통이 되고 ㅡ.ㅡ )

 

캡처본

최초 코드

import java.util.Arrays;
import java.util.Map;
import java.util.TreeMap;
class Solution {
    public int[] solution(int N, int[] stages) {
        int[] answer = new int[N];
		Arrays.sort(stages);
		int count = 0;
		//사람 수
		double people = stages.length;
   
		int[] stageCount = new int[N+1];
		int human = 0;
		double[] c = new double[N+1];
		// 스테이지별 머물러있는 사람 수를 구함(전부 완료한 사람은 N+1에)
		for(int j = 0; j <= N; j++) {
			count = 0;
			// 사람마다 비교해봄
			for(int i = human; i < people; i ++) {
				//System.out.println("단계 : " + (j+1) + " stages[i] " + stages[i]);
				if(stages[i] != j+1) {
					break;
				}
				count++;
				human++;
			}
			c[j] = count;
		}
		Map<Integer, Double> tm = new TreeMap<Integer, Double>();
		for(int i = 0; i <=N; i++) {
			double temp = people;
			people = people-c[i];
			c[i] = c[i]/temp;
			System.out.println("스테이지 "+i+"는 " + c[i]);
			if( i < N) {
				tm.put(i, c[i]);
			}
		}
		
		System.out.println(tm.toString());
		double[] answer2 = Arrays.copyOfRange(c, 0, N+1);
		
		Arrays.sort(answer2);
		answer2 = desc(answer2);
		answer2 = Arrays.copyOfRange(answer2, 1, answer2.length);
		int[] a = new int[answer2.length];
		int cc = 0;
		for(int i=0; i < answer2.length; i++) {
			for(int j=0; j < tm.size(); j++) {
				if(answer2[i]==tm.get(j)) {
					a[cc++] = (j+1);
					tm.replace(j, (double) -1);
				}
			}
			
		}
		return a;
	}
	public static double[] desc(double[] a) {
		double[] ar = new double[a.length];
		for(int i =0; i<a.length; i++) {
			ar[i] = a[a.length-i-1];
			System.out.println(i+"에 "+ar[i] + " 들어간다.");
		}
		return ar;
	}
}

수정 코드

1. stages를 정렬(오름차순)

2. 실패율이 소수점으로 나오기 때문에 처음부터 double로 선언해줌

3. 스테이지별로 몇명이 있는지 카운팅함

4. TreeMap을 선언해서 해당 스테이지가 실패율이 몇인지를 저장함

  (후에 스테이지를 키 값으로 실패율을 확인 가능)

5. 특정 스테이지에서 못넘어가는 경우( ... / 1 / 0 / 0 ..) 그러니까 나눌 수가 0인 경우는 전부 0으로 초기화 해버림

6. 오름차순 정렬 후 내림차순 정렬

  ( 내림차순의 방법이 따로 있으나 박싱, 언박싱, 북치고 장구치고 ㅈㄹ을 해야해서 따로 메소드 선언 후 뒤에서부터 반     환시켜버림 - > 훨씬 간단한듯. 물론 내생각에)

7. 내림차순으로 정렬된 값들이랑 트리에 저장된 값들이랑 비교해서 같은 놈의 키값을 새로 선언해준 int 배열에 차곡차     곡 넣어줌(실패율이 중복된 값들이 있어 삭제를 시키면 인덱스가 꼬여버림 그러므로 아예 -1로 만들어버림. 즉         remove 대신 replace 써줌)

Arrays.sort(stages);
		int count = 0;
		//사람 수
		double people = stages.length;
		int human = 0;
		double[] c = new double[N];
		// 스테이지별 머물러있는 사람 수를 구함(전부 완료한 사람은 N+1에)
		for(int j = 0; j < N; j++) {
			count = 0;
			// 사람마다 비교해봄
			for(int i = human; i < people; i ++) {
				//System.out.println("단계 : " + (j+1) + " stages[i] " + stages[i]);
				if(stages[i] != j+1) {
					break;
				}
				count++;
				human++;
			}
			c[j] = count;
		}
		for(int i = 0 ; i < c.length; i++) {
			System.out.println("test : " + i + " c[i] 값 = " + c[i]);
		}
		
		
		Map<Integer, Double> tm = new TreeMap<Integer, Double>();
		for(int i = 0; i <N; i++) {
			double temp = people;
			people = people-c[i];
				System.out.println("temp = " + temp);
				c[i] = c[i]/temp;
				if((int)temp == 0) {
					c[i] = 0;
				}
			System.out.println("스테이지 "+i+"는 " + c[i]);
			if( i < N) {
				tm.put(i, c[i]);
			}
		}
		
		System.out.println(tm.toString());
		
		Arrays.sort(c);
		c = desc(c);
		int[] a = new int[c.length];
		int cc = 0;
		for(int i=0; i < c.length; i++) {
			for(int j=0; j < tm.size(); j++) {
				if(c[i]==tm.get(j)) {
					a[cc++] = (j+1);
					tm.replace(j, (double) -1);
				}
			}
			
		}
		return a;
	}

	public static double[] desc(double[] a) {
		double[] ar = new double[a.length];
		for(int i =0; i<a.length; i++) {
			ar[i] = a[a.length-i-1];
			System.out.println(i+"에 "+ar[i] + " 들어간다.");
		}
		return ar;
	}