본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


Java(자바)/코딩 테스트 & 알고리즘

6. 기능개발 (프로그래머스, 스택/큐 Level 2)

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2021. 1. 19.

* 문제 설명

 - 프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다.
 - 또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고,

   이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다.
 - 먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와 각 작업의 개발 속도가 적힌

   정수 배열 speeds가 주어질 때 각 배포마다 몇 개의 기능이 배포되는지를 return 하도록 solution 함수를 완성하세요.

 

* 제한 사항
 - 작업의 개수(progresses, speeds배열의 길이)는 100개 이하입니다.
 - 작업 진도는 100 미만의 자연수입니다.
 - 작업 속도는 100 이하의 자연수입니다.
 - 배포는 하루에 한 번만 할 수 있으며, 하루의 끝에 이루어진다고 가정합니다.

   예를 들어 진도율이 95%인 작업의 개발 속도가 하루에 4%라면 배포는 2일 뒤에 이루어집니다.

* 입출력 예

progresses speeds return
[93, 30, 55] [1, 30, 5] [2, 1]
[95, 90, 99, 99, 80, 99] [1, 1, 1, 1, 1, 1] [1, 3, 2]

 

프로그래머스의 문제에서 가장 중요한 것은 문제를 이해하는 것 입니다.

문제가 사실 뭔말인지 어려워 한참 고민을 했던 것 같습니다.   * 머리가 나쁜걸까요..?ㅠ

 

맨 처음에 주어진 배열의 값은 일종의 종료가 필요한 도달값 입니다.

progresses의 각각의 값들이 100이 되면 종료의 개념입니다.

100을 향해서 증가하는 값은 바로 옆에 있는 speeds 입니다.

 

맨 첫번째 행에서의 93이라는 값의 속도는 1 입니다.

그러므로 하루에 1증가하기 때문에 7일이 걸리게 됩니다.

다음작업인 30은 속도가 30이므로 3일 걸리게 됩니다.

그리고 마지막 작업인 55는 속도가 5이므로  9일 걸리게 됩니다.

이를 저장하는 배열을 추가하여 줍니다.

    public static int[] solution(int[] progresses, int[] speeds) {
        int[] answer = new int[progresses.length];
        // 시간 측정
        for (int i = 0; i < progresses.length; i++) {
            int prog = progresses[i];
            int workingTime = 0;
            while (true) {
                if (prog >= 100)
                    break;
                prog += speeds[i];
                workingTime++;  //일한 시간 입니다.
            }
            answer[i] = workingTime;
        }
        System.out.println(Arrays.toString(answer));
    }

 

이를 실행하면 7, 3, 9의 값이 담겨진 배열을 확인 할 수 있습니다.

여기까진 뭐 어렵지 않습니다.

 

다음 개념입니다.

7일, 3일, 9일 걸리는 작업을 보면 첫번째 작업이 7일동안 동작해야 하므로 뒤에 있는 3일은 7일째 같이 종료가 됩니다.

그리고 9일 걸리는 작업은 9일 뒤에 종료가 되므로 이에 따른 결과는 [2, 1] 입니다.

이를 정리하여 보면,

#1. 첫번째 순서 조사
 - 데이터 : [7일, 3일, 9일]  
 - 7일보다 작으면 모두 7일 이내의 결과로 포함
 - 그러므로 결과는 2

#2. 두번째는 완료이므로 세번째로 건너가 조사
 - 데이터 : [완료, 완료, 9일]  
 - 9일보다 작으면 모두 9일 이내의 결과로 포함
 - 9일이 마지막이므로 결과는 1
 
#3. 결과 : [2, 1]
 

##추가 예시 --------

#1. 첫번째 순서 조사
 - 데이터 : [4일, 8일, 3일, 9일]  
 - 4일보다 작은수가 없으므로 결과는 1

#2. 두번째 순서 조사
 - 데이터 : [완료, 8일, 3일, 9일]  
 - 8일보다 작은수를 찾는데 3일이 존재함.
 - 8일, 3일 다음에 작은수가 없으므로 결과는 2
  
#3. 세번째는 완료 이므로 네번째로 건너가 조사
 - 데이터 : [완료, 완료, 완료, 9일]  
 - 9일보다 작은수를 찾는데 없으므로 결과는 1

#4. 결과 : [1, 2, 1]

 

위 규칙을 보면 나 말고 다음 데이터를 조사해야되는 규칙이 있으므로 2중 반복문이 필요하며,

조사가 완료되면 다음 조사에 포함되지 않는 값을 넣어주고 다음 차례로 넘겨야할 continue가 필요하여 보입니다.

ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < answer.length; i++) {  //기준값 입니다.
    int origin = answer[i];
    int count = 1;
    if (origin < 0) {  //조사가 완료된 대상이면 건너뛰기를 합니다.
        continue;
    }
    for (int j = i + 1; j < answer.length; j++) {  //기준값 다음의 값 입니다.
        int compare = answer[j];
        if (origin >= compare) {
            answer[j] = -1;  //조사가 완료되었으므로 대상에서 제거 합니다.
            count++;
        } else {
            break;
        }
    }
    list.add(count);
}

 

두근거리는 마음으로 결과를 제출하여 봅니다.

통과!

 

문제를 이해하는데 시간이 좀 걸리긴 하였지만, 한번에 통과하니 정말 기분이 좋았던 것 같습니다.

위 내용에 대한 전체 소스코드 입니다.

import java.util.ArrayList;

class Solution {
    public int[] solution(int[] progresses, int[] speeds) {
        int[] answer = new int[progresses.length];
        //시간 측정
        for(int i=0; i < progresses.length;i++){ 
        	int prog = progresses[i];
        	int workingTime = 0;
        	while(true){
        		if(prog >= 100) break;
        		prog += speeds[i];
        		workingTime++;  //일한 시간 입니다.
        	}
        	answer[i] = workingTime;
        }
        
        //값 확인
        ArrayList<Integer> list = new ArrayList<>();
        for(int i=0 ; i < answer.length ; i++){  //기준값 입니다.
            int origin = answer[i];
            int count = 1;
            if(origin < 0){continue;} //조사가 완료된 대상이면 건너뛰기를 합니다.
            for(int j=i+1 ; j < answer.length ; j++){  //기준값 다음의 값 입니다.
            	int compare = answer[j];
            	if(origin >= compare){
            		answer[j] = -1; //조사가 완료되었으므로 대상에서 제거 합니다.
            		count++;
            	} else {
            		break;
            	}
            }
            list.add(count);
        }        
        answer = list.stream().mapToInt(i ->i).toArray();
        return answer;
    }
}

 

이상으로 프로그래머스의 기능개발 문제에 대해서 정리하여 보았습니다.

궁금한 사항이나 틀린부분은 언제든 연락주세요! :)

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글