[CPU - Easy]

/**
 * <PRE>
 * 1. 개요
 *  
 * 처리해야 할 작업이 N개가 대기중이고 이를 처리하기위한 CPU가 있습니다. 
 * N개의 작업은 모두 동일한 작업이라고 가정합니다.
 * 작업을 수행하는 CPU에는 여러개의 코어가 있는데요. 코어별로 한 작업당 걸리는 시간이 다릅니다. 
 * 한 코어에서 작업이 끝나면 빈 코어에 다음 작업이 바로 들어가며, 2개 이상의 코어가 남을 경우 
 * 앞의 코어부터 채워줍니다. 
 *
 * 처리해야 될 작업의 개수 n과, 각 코어의 처리 시간이 담긴 배열 core가 주어질 때, 
 * 마지막 작업이 들어가는 코어의 번호를 반환해주는 getCoreNumber 함수를 완성하세요.
 * 
 * 예를 들어 작업이 6개이고, CPU의 코어별 처리 시간이 [1,2,3] 이라면 
 * 처음 3개의 작업은 각각 1,2,3번에 들어가고, 1의 시간 뒤 1번 코어에 4번째 작업, 
 * 다시 1의 시간 뒤 1,2번 코어에 5,6번 째 작업이 들어가므로 2를 반환해 주면 됩니다.
 * 
 * 2. 예상 결과
 * 
 * 예상 결과는 하기 코드 실행시 예상되는 결과 값입니다.
 * 결과 : 작업이 6개인 경우, 최종 작업이 들어가는 코어의 번호는 2입니다.
 * 
 * </PRE>
 *
 * @author    이준표
 */
public class Test10 {

	private static final String result = "작업이 %d개인 경우, 최종 작업 코어번호 = %d";

	public static void main( String[] args ) {
		// 시작시간 기록
		long startTime = System.currentTimeMillis();

		// STEP 1. TEST 데이터 준비 (코어 성능)
		int[] core = { 1, 2, 3 }; //각 코어의 성능
		int count = 6;           //작업의 개수
		
		// STEP 2. 코어 산출
		int answer = getCoreNumber( count, core );

		System.out.println( String.format( result, count, answer ) );

		// 종료시간 기록
		long endTime = System.currentTimeMillis() - startTime;
		System.out.println( "소요시간 : " + endTime + "ms." );

	}

	/**
	 * 
	 * <PRE>
	 * 최종 작업이 들어갈 코어를 구한다.
	 * </PRE>
	 * 
	 * @param workCnt : 수행해야할 작업 수
	 * @param cores : 수행할 코어들
	 * @return
	 */
	public static int getCoreNumber( int workCnt, int[] cores ) {
		int answer = 0; // 결과데이터
		int cycle = 0; // 코어에 작업을 배분하는 사이클(1초)

		// STEP 1. 남아있는 작업을 모두 코어에 배분한다.
		outer: while ( workCnt > 0 ) {

			// STEP 2. 모든 코어들이 작업을 배분받는다.
			for ( int inx = 0 ; inx < cores.length ; inx++ ) {

				/*
				STEP 3. 각 코어마다 정해진 코어 사이클이 
				         종료된 경우 새로운 작업을 배분받는다.
				*/ 
				if ( cycle % cores[inx] == 0 ) {
					// STEP 3-1. 작업 할당
					workCnt--;

					// STEP 3-2. 마지막 작업을 할당한 경우, 코어번호 반환
					if ( workCnt == 0 ) {
						answer = inx + 1; // 배열은 0부터 시작
						break outer;
					}
				}
			}
			// STEP 4. 사이클이 1초 증가한다.
			cycle++;
		}
		return answer;
	}
}