ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Algo RhythmπŸ•ΊπŸ’ƒ] ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ 고득점 kit λ””μŠ€ν¬ 컨트둀러
    Algo RhythmπŸ•ΊπŸ’ƒ/Programmers 2020. 7. 16. 02:30

    πŸ“š 문제 μ„€λͺ…

    ν•˜λ“œλ””μŠ€ν¬λŠ” ν•œ λ²ˆμ— ν•˜λ‚˜μ˜ μž‘μ—…λ§Œ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ””μŠ€ν¬ 컨트둀러λ₯Ό κ΅¬ν˜„ν•˜λŠ” 방법은 μ—¬λŸ¬ 가지가 μžˆμŠ΅λ‹ˆλ‹€. κ°€μž₯ 일반적인 방법은 μš”μ²­μ΄ λ“€μ–΄μ˜¨ μˆœμ„œλŒ€λ‘œ μ²˜λ¦¬ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

     

    예λ₯Όλ“€μ–΄

     

    - 0ms μ‹œμ μ— 3msκ°€ μ†Œμš”λ˜λŠ” Aμž‘μ—… μš”μ²­
    - 1ms μ‹œμ μ— 9msκ°€ μ†Œμš”λ˜λŠ” Bμž‘μ—… μš”μ²­
    - 2ms μ‹œμ μ— 6msκ°€ μ†Œμš”λ˜λŠ” Cμž‘μ—… μš”μ²­

     

    와 같은 μš”μ²­μ΄ λ“€μ–΄μ™”μŠ΅λ‹ˆλ‹€. 이λ₯Ό 그림으둜 ν‘œν˜„ν•˜λ©΄ μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

     

     

    ν•œ λ²ˆμ— ν•˜λ‚˜μ˜ μš”μ²­λ§Œμ„ μˆ˜ν–‰ν•  수 있기 λ•Œλ¬Έμ— 각각의 μž‘μ—…μ„ μš”μ²­λ°›μ€ μˆœμ„œλŒ€λ‘œ μ²˜λ¦¬ν•˜λ©΄ λ‹€μŒκ³Ό 같이 처리 λ©λ‹ˆλ‹€.

     

     

    - A: 3ms μ‹œμ μ— μž‘μ—… μ™„λ£Œ (μš”μ²­μ—μ„œ μ’…λ£ŒκΉŒμ§€ : 3ms)
    - B: 1msλΆ€ν„° λŒ€κΈ°ν•˜λ‹€κ°€, 3ms μ‹œμ μ— μž‘μ—…μ„ μ‹œμž‘ν•΄μ„œ 12ms μ‹œμ μ— μž‘μ—… μ™„λ£Œ(μš”μ²­μ—μ„œ μ’…λ£ŒκΉŒμ§€ : 11ms)
    - C: 2msλΆ€ν„° λŒ€κΈ°ν•˜λ‹€κ°€, 12ms μ‹œμ μ— μž‘μ—…μ„ μ‹œμž‘ν•΄μ„œ 18ms μ‹œμ μ— μž‘μ—… μ™„λ£Œ(μš”μ²­μ—μ„œ μ’…λ£ŒκΉŒμ§€ : 16ms)

     

    이 λ•Œ 각 μž‘μ—…μ˜ μš”μ²­λΆ€ν„° μ’…λ£ŒκΉŒμ§€ κ±Έλ¦° μ‹œκ°„μ˜ 평균은 10ms(= (3 + 11 + 16) / 3)κ°€ λ©λ‹ˆλ‹€.

    ν•˜μ§€λ§Œ A → C → B μˆœμ„œλŒ€λ‘œ μ²˜λ¦¬ν•˜λ©΄

     

     

    - A: 3ms μ‹œμ μ— μž‘μ—… μ™„λ£Œ(μš”μ²­μ—μ„œ μ’…λ£ŒκΉŒμ§€ : 3ms)
    - C: 2msλΆ€ν„° λŒ€κΈ°ν•˜λ‹€κ°€, 3ms μ‹œμ μ— μž‘μ—…μ„ μ‹œμž‘ν•΄μ„œ 9ms μ‹œμ μ— μž‘μ—… μ™„λ£Œ(μš”μ²­μ—μ„œ μ’…λ£ŒκΉŒμ§€ : 7ms)
    - B: 1msλΆ€ν„° λŒ€κΈ°ν•˜λ‹€κ°€, 9ms μ‹œμ μ— μž‘μ—…μ„ μ‹œμž‘ν•΄μ„œ 18ms μ‹œμ μ— μž‘μ—… μ™„λ£Œ(μš”μ²­μ—μ„œ μ’…λ£ŒκΉŒμ§€ : 17ms)

     

    μ΄λ ‡κ²Œ A → C → B의 μˆœμ„œλ‘œ μ²˜λ¦¬ν•˜λ©΄ 각 μž‘μ—…μ˜ μš”μ²­λΆ€ν„° μ’…λ£ŒκΉŒμ§€ κ±Έλ¦° μ‹œκ°„μ˜ 평균은 9ms(= (3 + 7 + 17) / 3)κ°€ λ©λ‹ˆλ‹€.

    각 μž‘μ—…μ— λŒ€ν•΄ [μž‘μ—…μ΄ μš”μ²­λ˜λŠ” μ‹œμ , μž‘μ—…μ˜ μ†Œμš”μ‹œκ°„]을 담은 2차원 λ°°μ—΄ jobsκ°€ λ§€κ°œλ³€μˆ˜λ‘œ μ£Όμ–΄μ§ˆ λ•Œ, μž‘μ—…μ˜ μš”μ²­λΆ€ν„° μ’…λ£ŒκΉŒμ§€ κ±Έλ¦° μ‹œκ°„μ˜ 평균을 κ°€μž₯ μ€„μ΄λŠ” λ°©λ²•μœΌλ‘œ μ²˜λ¦¬ν•˜λ©΄ 평균이 μ–Όλ§ˆκ°€ λ˜λŠ”μ§€ return ν•˜λ„λ‘ solution ν•¨μˆ˜λ₯Ό μž‘μ„±ν•΄μ£Όμ„Έμš”. (단, μ†Œμˆ˜μ  μ΄ν•˜μ˜ μˆ˜λŠ” λ²„λ¦½λ‹ˆλ‹€)

     

    μ œν•œ 사항

    • jobs의 κΈΈμ΄λŠ” 1 이상 500 μ΄ν•˜μž…λ‹ˆλ‹€.

    • jobs의 각 행은 ν•˜λ‚˜μ˜ μž‘μ—…μ— λŒ€ν•œ [μž‘μ—…μ΄ μš”μ²­λ˜λŠ” μ‹œμ , μž‘μ—…μ˜ μ†Œμš”μ‹œκ°„] μž…λ‹ˆλ‹€.

    • 각 μž‘μ—…μ— λŒ€ν•΄ μž‘μ—…μ΄ μš”μ²­λ˜λŠ” μ‹œκ°„μ€ 0 이상 1,000 μ΄ν•˜μž…λ‹ˆλ‹€.

    • 각 μž‘μ—…μ— λŒ€ν•΄ μž‘μ—…μ˜ μ†Œμš”μ‹œκ°„μ€ 1 이상 1,000 μ΄ν•˜μž…λ‹ˆλ‹€.

    • ν•˜λ“œλ””μŠ€ν¬κ°€ μž‘μ—…μ„ μˆ˜ν–‰ν•˜κ³  μžˆμ§€ μ•Šμ„ λ•Œμ—λŠ” λ¨Όμ € μš”μ²­μ΄ λ“€μ–΄μ˜¨ μž‘μ—…λΆ€ν„° μ²˜λ¦¬ν•©λ‹ˆλ‹€.

     

    🎯 μ–΄λ–»κ²Œ ν’€μ—ˆλ‚˜

    첫번째 μ‹œλ„  (40점 / 100점)

    import java.util.Comparator;
    import java.util.PriorityQueue;
    
    class Job {
        public int tReq;
        public int period;
        
        public Job(int tReq, int period){
            this.tReq = tReq;
            this.period = period;
        }
        
        public int getTReq(){
            return this.tReq;
        }
        
        public int getPeriod() {
            return this.period;
        }
    }
    
    class Solution {
        public int solution(int[][] jobs) {
            int avg = 0, sum = 0;
            int nJob = jobs.length;
            int jIdx = 0;
            int t = 0;
            int tRemaining = 0; // remaining time of current working job to be done
            
            PriorityQueue<Job> tReqQ = new PriorityQueue<>(Comparator.comparing(Job::getTReq));
            PriorityQueue<Job> periodQ = new PriorityQueue<>(Comparator.comparing(Job::getPeriod));
            
            // Phase 1 : init tReqQ
            for(int i = 0;i < nJob; i++) {
                int tReq = jobs[i][0];
                int period = jobs[i][1];
                
                tReqQ.offer(new Job(tReq, period));
            }
            
            
            while(!tReqQ.isEmpty() || !periodQ.isEmpty()) { 
                if(!tReqQ.isEmpty() && t == tReqQ.peek().tReq) {
                    Job j = tReqQ.poll();
                    
                    periodQ.offer(new Job(j.tReq, j.period));
                }
                
                if(!periodQ.isEmpty() && tRemaining == 0) {
                    Job j = periodQ.poll();
                    
                    tRemaining += j.period;
                    sum += (j.period + t - j.tReq); // (tReq ~ tEnd) = period + (tStart - tReq) = period + tDelay
                }
                
                if(tRemaining > 0) {
                    tRemaining--;
                }
                
                t++;
            }      
            
            avg = sum / nJob;
            
            return avg;
        }
    }

     

    λ‘λ²ˆμ§Έ μ‹œλ„

    import java.util.Arrays;
    import java.util.Comparator;
    import java.util.PriorityQueue;
    
    class Job {
        public int tReq;
        public int period;
        
        public Job(int tReq, int period){
            this.tReq = tReq;
            this.period = period;
        }
        
        public int getPeriod() {
            return this.period;
        }
    }
    
    class Solution {
        public int solution(int[][] jobs) {
            int avg = 0, sum = 0;
            int nJob = jobs.length;
            int jIdx = 0;
            int t = 0;
            int tRemaining = 0; // remaining time of current working job to be done
            
            PriorityQueue<Job> periodQ = new PriorityQueue<>(Comparator.comparing(Job::getPeriod));
            
            // Phase 1 : sort jobs by tReq
            Arrays.sort(jobs, (j1, j2) -> Integer.compare(j1[0], j2[0]));
            
            // Phase 2
            while(jIdx < nJob || !periodQ.isEmpty()) {
                while(jIdx < nJob && t >= jobs[jIdx][0]){ // κ°€λŠ₯ν•œ jobλ“€ 큐에 λ„£κΈ°
                    int tReq = jobs[jIdx][0];
                    int period = jobs[jIdx][1];
                    
                    periodQ.offer(new Job(tReq, period));
                    jIdx++;
                }
                
                if(!periodQ.isEmpty()) { //큐가 λΉ„μ–΄ μžˆμ§€ μ•ŠμœΌλ©΄ 일할 수 μžˆλŠ” μƒνƒœ
                    Job j = periodQ.poll();
                    sum += j.period + (t - j.tReq); // (tReq ~ tEnd) = period + (tStart - tReq) = period + tDelay
                    t += j.period;
                }
                else { // 큐가 λΉ„μ–΄ 있으면 일할 수 μ—†λŠ” μƒνƒœ
                    t = jobs[jIdx][0]; 
                }
            }
            
            avg = sum / nJob;
            
            return avg;
        }
    }

     

    🧐 μ™œ μ €λ ‡κ²Œ ν’€μ—ˆλ‚˜

    첫번째 μ‹œλ„ (40점/ 100점)

    μ•Œκ³ λ¦¬μ¦˜μ˜ 핡심을 νŒŒμ•…ν•˜λŠ” 것은 어렡지 μ•Šμ•˜λ‹€. μ™œλƒν•˜λ©΄ OSμ‹œκ°„μ— SJF(Short Job First) μŠ€μΌ€μ€„λ§ μ•Œκ³ λ¦¬μ¦˜μ„ λ°°μ› κΈ° λ•Œλ¬Έμ΄λ‹€. κ·Έλž˜μ„œ μ‹œκ°„μ„ μ¦κ°€ν•˜λ©΄μ„œ μ‹€ν–‰ κ°€λŠ₯ν•œ μž‘μ—…λ“€μ„ λͺ¨λ‘ μ†Œμš”μ‹œκ°„μ„ κΈ°μ€€μœΌλ‘œ ν•œ μ΅œμ†Œ νž™μ— λ„£κ³  μ‹€ν–‰ν•  수 μžˆλŠ” μƒνƒœκ°€ 될 λ•Œλ§ˆλ‹€ μ‹€ν–‰ν•˜λ©° μš”μ²­λΆ€ν„° μ’…λ£ŒκΉŒμ§€ μ†Œμš”λœ μ‹œκ°„μ˜ 평균을 κ΅¬ν•˜κΈ°λ‘œ ν–ˆλ‹€.

     

    λ¨Όμ € μž‘μ—…μ˜ μš”μ²­ μ‹œμ κ³Ό μ†Œμš”μ‹œκ°„μ„ 멀버 λ³€μˆ˜λ‘œ κ°€μ§€λŠ” Jobμ΄λΌλŠ” 클래슀λ₯Ό λ§Œλ“€μ—ˆλ‹€.

    그리고 Job의 μš”μ²­ μ‹œμ μ„ κΈ°μ€€μœΌλ‘œ ν•œ μ΅œμ†Œ νž™μΈ tReqQ와 Job의 μ†Œμš” μ‹œκ°„μ„ κΈ°μ€€μœΌλ‘œ ν•œ μ΅œμ†Œ νž™μΈ periodQλ₯Ό λ§Œλ“€μ—ˆλ‹€.

    tReqQλŠ” λ§€κ°œλ³€μˆ˜λ‘œ μ£Όμ–΄μ§€λŠ” 2차원 λ°°μ—΄ jobsκ°€ μš”μ²­ μ‹œμ μ— 따라 μ˜€λ¦„ 차순으둜 μ •λ ¬λ˜μ–΄ μžˆλ‹€λŠ” 보μž₯이 μ—†κΈ° λ•Œλ¬Έμ— λ§Œλ“€μ—ˆκ³  periodQλŠ” κ°€λŠ₯ν•œ Job듀을 λͺ¨μœΌκ³  κ·Έ 쀑 μ†Œμš” μ‹œκ°„μ΄ κ°€μž₯ 짧은 Job을 λΉ λ₯΄κ²Œ μ°ΎκΈ° μœ„ν•΄ λ§Œλ“€μ—ˆλ‹€.

     

    κ·Έ λ‹€μŒλΆ€ν„°λŠ” κ°„λ‹¨ν•˜λ‹€. 두 νž™μ΄ λͺ¨λ‘ λΉ„μ–΄μ§ˆ λ•ŒκΉŒμ§€ λ‹€μŒμ„ λ°˜λ³΅ν•œλ‹€.

    tReqQμ—μ„œ κΊΌλ‚Έ Job의 μš”μ²­μ‹œκ°„μ΄ ν˜„μž¬ μ‹œκ°„κ³Ό κ°™μœΌλ©΄ periodQ에 κ·Έ job을 λ„£λŠ”λ‹€.

    일을 ν•  수 μžˆλŠ” μƒνƒœ(= μ–΄λ–€ 일이 λλ‚˜κΈ°κΉŒμ§€ κ±Έλ¦¬λŠ” μ‹œκ°„μ΄ 0μΌλ•Œ) periodQμ—μ„œ job ν•˜λ‚˜λ₯Ό κΊΌλ‚Έλ‹€.

    μ‹œκ°„μ„ 1μ”© μ¦κ°€ν•œλ‹€.

     

    이둠상 λ™μž‘ν•˜κΈ΄ λ™μž‘ν•˜λŠ” μ½”λ“œμ§€λ§Œ μ‹œκ°„ μ΄ˆκ³Όμ— λ”± 걸렀버렸닀...

    더 효율적으둜 μ½”λ“œλ₯Ό μˆ˜μ •ν•  ν•„μš”κ°€ μžˆμ—‡λ‹€.

     

    λ‘λ²ˆμ§Έ μ‹œλ„

    λ‘λ²ˆμ§Έ μ‹œλ„λŠ” λ‹€λ₯Έ λΆ„μ˜ μ½”λ“œλ₯Ό μ°Έκ³ ν•΄μ„œ ν•΄κ²°ν–ˆλ‹€.

    핡심은 μ²«λ²ˆμ§Έμ™€ λ‹€λ₯΄μ§€ μ•Šλ‹€. ν•˜μ§€λ§Œ μ‹œκ°„μ„ μ¦κ°€ν•˜λŠ” 방식에 μžˆμ–΄μ„œ 첫번째 μ‹œλ„λŠ” 쀑간에 λΆ• 뜬 μ‹œκ°„μ„ λͺ¨λ‘ λ°˜λ³΅ν•΄μ•Ό ν–ˆμ§€λ§Œ λ‘λ²ˆμ§Έ μ‹œλ„λŠ” 쀑간에 λΆ• 뜬 μ‹œκ°„μ€ λ¬΄μ‹œν•œλ‹€λŠ” μ μ—μ„œ λ‹€λ₯΄λ‹€.

     

    πŸ“– 무엇을 λ°°μ› λ‚˜

    OS λ•Œ 배운 SJF(Short Job First) μ•Œκ³ λ¦¬μ¦˜μ„ κ΅¬ν˜„ν•΄μ„œ 재밌고 λ°˜κ°€μ› λ‹€.

    그리고 λ‚˜λŠ” '더 효율적으둜 ν’€ μˆ˜λŠ” μ—†μ„κΉŒ? 이게 μ΅œμ„ μΌκΉŒ?' 라고 늘 μ§ˆλ¬Έν•˜λŠ” μžμ„Έκ°€ ν•„μš”ν•˜λ‹€λŠ” 것을 λ°°μ› λ‹€.

    λŒ“κΈ€

Designed by Tistory.