ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C# 프로그래머스 Lv2 기능 개발
    코딩테스트 2020. 8. 20. 11:42
    • 기능개발
    • darklight

      sublimevimemacs

      C# 

    문제 설명

    프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 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개의 기능이 배포됩니다.

    ※ 공지 - 2020년 7월 14일 테스트케이스가 추가되었습니다.


    풀이

    작업이 완료되는 시점을 구하는 문제가 아닌 작업이 완료되는 시점에 몇개의 작업이 완료되었는지를 구하는 문제이다. 

    test_case 의 [93,30,55] [1,30,5] [2,1] 로 놓고 봤을 때

     

    1. 작업이 완료되는데 필요한 시간 구하기 (작업 별 걸리는 시간 flag)

    93에 1씩 더한다. 100이 되거나 100보다 커지는 순간의 i 즉 시간을 flag에 저장한다.    => 7

    30에 30씩 더한다. 100이 되거나 100보다 커지는 순간의 i 즉 시간을 flag에 저장한다.   => 3

    55에 5씩 더한다. 100이 되거나 100보다 커지는 순간의 i 즉 시간을 flag에 저장한다.     => 9

    for (date = 0; date < progresses.Length; date++)
    {
    	for (int i = 0; i < 100; i++)
    	{
    		if (progresses[date] < 100)
    		{
    			progresses[date] = progresses[date] + speeds[date];
    		}
    		else if (progresses[date] >= 100)
    		{
    			flag[date] = i;
    			break;
    		}
    	}
    }//flag에 완료까지 걸리는 일자 계산 7일 3일 9일

     

    2. 앞에 작업이 뒤의 작업보다 오래 걸리는지 확인하기

    앞의 작업이 뒤의 작업보다 오래걸렸다면 앞 뒤 작업이 같은 날에 배포가 된다.

    위에서 각 작업별 걸리는 시간

    temp = [7,3,9]

    7과 7을 비교 : count ++ 

    7과 3을 비교 : count ++

    7과 9를 비교 : break; 앞의 두 공정보다 이틀 뒤에 나오므로 같은날 나오지 않는다.

    첫날에 count++을 두번했으니 2개 배포

     

    3과 3을 비교 count++

    3과 9를 비교 break

    첫 작업이 끝난 날 둘째 작업도 끝났으니 7,3 이 배포되서 1이 아니지만 일단 1을 저장해놓는다.

     

    9와 9를 비교 count++

    반복문 조건 종료

    혼자 배포된다.

    for (int i = count; i < speeds.Length; i++)
    {
    	for (int j = i; j < speeds.Length; j++)
    	{
    		if (flag[i] >= flag[j])
    		{
    			count++;
    		}
    		else if (flag[i] < flag[j])
    		{
    			break;
    		}
    	}
    	if (count > 1 || count == 1)
    	{
    		progress_Queue1.Enqueue(count);
    	}
    	count = 0;
    } 
    //앞 프로세스 뒤 프로세스 비교해서 앞이 더 오래걸리거나 같으면 count++
    temp = progress_Queue1.ToArray();

    따라서 위 테스트케이스의 결과로는 여기까지 [2,1,1]이 temp에 저장된다.

     

    3. 앞에서 작업이 끝난 즉 temp[i]가 1보다 클 경우 temp[i]만큼 뒤에 배열 clear

    for (int i = 0; i < temp.Length; i++)
    {
      if (temp[i] > 1) 
     	 Array.Clear(temp, i + 1, temp[i] - 1);
    }
    //앞이 끝났는데 뒤 프로세스는 1을 잡고 있으니 앞 프로세스의 출고개수만큼 뒤 출고개수 삭제

    4. clear된 부분 지워주기

     for (int i = 0; i < temp.Length; i++)
     {
     	if (temp[i] >= 1)
     		progress_Queue2.Enqueue(temp[i]);
     }
     temp = progress_Queue2.ToArray();
     return temp;

     

     

     

     

     

    using System;
        using System.Collections.Generic;
        public class Solution
        {
            public int[] solution(int[] progresses, int[] speeds)
            {
                // 93, 30, 55 
                // 1, 30 , 5
                // 2,1
                Queue<int> progress_Queue1 = new Queue<int>();
                Queue<int> progress_Queue2 = new Queue<int>();
                int[] flag = new int[speeds.Length];
                int[] temp = new int[speeds.Length];
                int date = 0;
    
                for (date = 0; date < progresses.Length; date++)
                {
                    for (int i = 0; i < 100; i++)
                    {
                        if (progresses[date] < 100)
                        {
                            progresses[date] = progresses[date] + speeds[date];
                        }
                        else if (progresses[date] >= 100)
                        {
                            flag[date] = i;
                            break;
                        }
                    }
                }//flag에 완료까지 걸리는 일자 계산 7일 3일 9일
                
                int count = 0;
    
                for (int i = count; i < speeds.Length; i++)
                {
    
                    for (int j = i; j < speeds.Length; j++)
                    {
                        if (flag[i] >= flag[j])
                        {
                            count++;
                        }
                        else if (flag[i] < flag[j])
                        {
                            break;
                        }
                    }
                    if (count > 1 || count == 1)
                    {
                        progress_Queue1.Enqueue(count);
                    }
                    count = 0;
                } 
                //앞 프로세스 뒤 프로세스 비교해서 앞이 더 오래걸리거나 같으면 count++
                temp = progress_Queue1.ToArray();
               
    
                for (int i = 0; i < temp.Length; i++)
                {
                    if (temp[i] > 1) 
                        Array.Clear(temp, i + 1, temp[i] - 1);
                }
                //앞이 끝나야 뒤에 프로세스도 같이 끝나므로 앞 프로세스의 출고개수만큼 뒤 출고개수 삭제
    
                foreach (var item in temp)
                {
                    Console.Write(item + " ");
                }
                Console.WriteLine();
    
                for (int i = 0; i < temp.Length; i++)
                {
                    if (temp[i] >= 1)
                        progress_Queue2.Enqueue(temp[i]);
                }
                temp = progress_Queue2.ToArray();
                return temp;
            }
        }
Designed by Tistory.