본문 바로가기

취업관련/코딩테스트

기능 개발

 

프로그래머스에서 제공하는 문제들 중 스택과 큐를 연습하기 위한 문제를 풀었다.

문제 링크 : https://programmers.co.kr/learn/courses/30/lessons/42586

 

코딩테스트 연습 - 기능개발 | 프로그래머스

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다. 또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고, 이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다. 먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와 각 작업의 개발 속도가 적힌 정수 배열 speeds가 주어질 때 각 배포마다 몇

programmers.co.kr

 

문제 설명

문제 설명 및 예시


풀이 과정

우선도 순으로 입력한 배열과 각 기능들의 개발 속도를 입력한 배열을 각가 넣어주었을 때 우선도가 가장 높은 기능이 릴리즈될 당시 몇 개의 기능과 함께 릴리즈되는지를 반환하도록 하며 완성도가 100%를 달성하더라도 각 요일이 끝났을 때 일괄적으로 릴리즈를 수행하게 된다.

문제를 효율적으로 풀이하기 위해 큐를 사용하기로 했으며 함께 공개될 기능을 셀 변수와 며칠이 걸릴지 계산할 변수를 각각 선언해주었다.

풀이를 위해 생각한 방법은 큐에 존재하는 요소가 없을 때까지 반복하며 요일을 계속 1씩 추가하는 동안 각 기능의 구현도를 계속 확인하며 한 기능의 구현도가 100%를 넘겼을 때 해당 기능을 공개하도록 했다. 또한 poll()메소드를 호출한 후에 다음 큐를 한 번에 비교하며 함께 완료가 되는 기능을 확인하기 위한 변수까지 활용하도록 하는 것으로 계획을 세웠다.

완료된 기능들의 수는 정확하게 몇개가 되는지 확실하게 알 수 없어 배열의 크기는 가변적이 될 수밖에 없을 것이라 판단했다. 그렇기 때문에 ArrayList를 활용해 가변적인 배열 크기에 대응할 수 있도록 했다.

계산 과정에서는 문제가 없었으나 마지막 부분에서 NullPointerException이 발생했다.

NullPointerException이 발생하는 원인을 찾아보니 모든 결과들이 나온 후에도 while문의 계산결과 > 100의 조건이 계속 진행되며 비어있는 큐를 가리키려 했기 때문이었던 것을 찾아낼 수 있었다.

원인을 해결하기 위해서 while문의 종료 조건에 추가적으로 !isEmpty()메소드를 넣어주게 되었다.

while (!prog.isEmpty()) {
    int comp = prog.peek() + days * speeds[index];
			
    if (comp >= 100) {
        prog.poll();
        index++;
        count++;
    
        ...

 

마지막으로 가변 크기를 제어해주기 위한 ArrayList는 문제에서 요구하는 int형 배열로 반환하기에 적합하지 않은 상태를 띄고 있었기 때문에 배열로의 변환이 필요했고, Iterator를 활용해 무사히 배열로 변환을 마칠 수 있게 되었다.

int[] resultArray = new int[list.size()];
Iterator<Integer> it = list.iterator();
		
for (int i = 0; i < list.size(); i++)
    resultArray[i] = it.next();
		
return resultArray;

 

최종 코드

package StackQueueProblem;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class FunctionDevelopment {
	public static void main(String[] args) {
		init();
	}
	
	static void init() {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		try {
			String input = br.readLine();
			StringTokenizer st = new StringTokenizer(input);
			int[] progresses = new int[st.countTokens()];
			int index = 0;
			
			while (st.hasMoreTokens())
				progresses[index++] = Integer.parseInt(st.nextToken());
			
			input = br.readLine();
			st = new StringTokenizer(input);
			index = 0;
			int[] speeds = new int[st.countTokens()];
			
			while (st.hasMoreTokens())
				speeds[index++] = Integer.parseInt(st.nextToken());
			
			bw.write(Arrays.toString(solution(progresses, speeds)));
			bw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	static int[] solution(int[] progresses, int[] speeds) {
		Queue<Integer> prog = new LinkedList<>();
		ArrayList<Integer> list = new ArrayList<>();
		
		int count = 0; //동시에 완료된 기능이 몇개인지 세는 변수
		int days = 1; //가장 앞선 중요도의 기능이 며칠이나 걸렸는지 세는 변수
		int index = 0;
		
		for (int i : progresses)
			prog.offer(i);
		
		while (!prog.isEmpty()) {
			int comp = prog.peek() + days * speeds[index];
			
			if (comp >= 100) {
				prog.poll();
				index++;
				count++;
				
				while (!prog.isEmpty()) {
					if ((prog.peek() + days * speeds[index]) >= 100) {
						prog.poll();
						index++;
						count++;
					} else
						break;
				}
				
				list.add(count);
				count = 0;
			}
			
			days++;
		}
		
		int[] resultArray = new int[list.size()];
		Iterator<Integer> it = list.iterator();
		
		for (int i = 0; i < list.size(); i++)
			resultArray[i] = it.next();
		
		return resultArray;
	}
}

 

채점 결과

'취업관련 > 코딩테스트' 카테고리의 다른 글

소수 찾기  (0) 2019.10.19
H-Index  (0) 2019.10.13
프린터  (0) 2019.10.06
베스트 앨범  (0) 2019.10.06
  (0) 2019.10.06