본문 바로가기
알고리즘/프로그래머스

[프로그래머스] 기능 개발 (level.2) java

by 코리늬 2019. 3. 25.

프로그래머스 기능개발

기능개발
문제 설명

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다.

또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고,
이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다.

먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와
각 작업의 개발 속도가 적힌 정수 배열 speeds가 주어질 때
각 배포마다 몇 개의 기능이 배포되는지를 return 하도록 solution 함수를 완성하세요.

제한 사항
작업의 개수(progresses, speeds배열의 길이)는 100개 이하입니다.
작업 진도는 100 미만의 자연수입니다.
작업 속도는 100 이하의 자연수입니다.
배포는 하루에 한 번만 할 수 있으며, 하루의 끝에 이루어진다고 가정합니다.
예를 들어 진도율이 95%인 작업의 개발 속도가 하루에 4%라면 배포는 2일 뒤에 이루어집니다.

입출력 예
progresses speeds return
[93,30,55] [1,30,5]   [2,1]

입출력 예 설명
첫 번째 기능은 93% 완료되어 있고 하루에 1%씩 작업이 가능하므로 7일간 작업 후 배포가 가능합니다.
두 번째 기능은 30%가 완료되어 있고 하루에 30%씩 작업이 가능하므로 3일간 작업 후 배포가 가능합니다.
하지만 이전 첫 번째 기능이 아직 완성된 상태가 아니기 때문에 첫 번째 기능이 배포되는 7일째 배포됩니다.
세 번째 기능은 55%가 완료되어 있고 하루에 5%씩 작업이 가능하므로 9일간 작업 후 배포가 가능합니다.

따라서 7일째에 2개의 기능, 9일째에 1개의 기능이 배포됩니다.
*
* 먼저 들어온놈이 먼저 나가야한다. 뒤에들어온 놈이 다 완성 되어도 앞에 들어온 놈이 완료될 때 나갈 수 있다.
* 작업은 100이 완료, speed 1마다 하루로 계산된다.


자료구조는 시간이 조금만 지나도 다 까먹는다..

언제쯤 손쉽게 구현할까


의사코드

문제를 읽어보니, 결과값을 비교하기 위해서는 몇일간 작업을 해야할지에 대한 정보가 필요했다.

작업은 최대 100개까지 있고 speeds 배열의 값 만큼 하루에 진행 가능하다.

그래서 (100 - progresses[i]) 을 한 수를 % speeds[i] 로 나누어, 0 인경우는 몫 값을 그대로 사용하고, 아닌 경우는 + 1일을 해줘야겠다고 생각했다.

그 후 앞 뒤를 비교하면 끝


느낀점

작업일을 구하는 것 까지는 쉬웠다.

하지만 이제 앞 뒤를 비교하는데서 난관이었다.

단순히 버블정렬 처럼 앞뒤를 비교하려했으나 어딘가 자꾸 안맞았다.

스택/큐 문제를 내가 풀기 편한방식으로 해보려했으나 실패.

구현한 방법은 비교할 뒤의 숫자를 따로 저장해놓고, que.peek()를 사용해 맨 앞과 비교 후, poll()을 사용해 더이상 쓸모 없어진 수를 날려버리면서 카운트를 해준다.

하지만 여기서 큐가 비어있는지 확인을 계속 해줄 수 있어야 했다.

나한테 최선의 방법이었다.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;

public class FunctionDev {
   public int[] solution(int[] progresses, int[] speeds) {
       int length = progresses.length;
       Queue<Integer> que = new LinkedList<>();
       ArrayList<Integer> list = new ArrayList<>();

       //남은 일 수 계산
       getWorkDay(progresses, speeds, length, que);

       //카운트 계산
       int cnt = getCnt(que, list);

       //카운트가 0이아닌 경우 추가
       if (cnt !=0){
           list.add(cnt);
      }
       int size = list.size();
       int answer[] = new int[size];

       for(int i=0; i<size; i++){
           answer[i] = list.get(i);
      }
       //System.out.println(Arrays.toString(answer));
       return answer;

  }

   private int getCnt(Queue<Integer> que, ArrayList<Integer> list) {
       int cnt=0;
       int target;
       while(!que.isEmpty()){
           target = que.poll();
           cnt++;

           while(!que.isEmpty()){
               if (que.peek() > target){
                   list.add(cnt);
                   cnt=0;
                   break;
              }else{
                   que.poll();
                   cnt++;
              }
          }
      }
       return cnt;
  }

   private Queue getWorkDay(int[] progresses, int[] speeds, int length, Queue<Integer> que) {
       int date;
       int workDay;

       for (int i = 0; i<length; i++){
            date = 100 - progresses[i];
           if(date %speeds[i] != 0 ){
               workDay = date/speeds[i] + 1;

               System.out.println(workDay);
          }else {
               workDay = date/speeds[i];
               System.out.println(date/speeds[i]);
          }
           que.add(workDay);
      }
       return que;
  }

  /* public static void main(String[] args) {
       FunctionDev f = new FunctionDev();
       f.solution(new int[]{93,30,55}, new int[]{1,30,5});
   }*/
}


댓글