[ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค] ๊ณผ์ œ ์ง„ํ–‰ํ•˜๊ธฐ(Python, Stack, Implementation)

    ๋ฐ˜์‘ํ˜•

    ๐ŸŒฑ ๋ฌธ์ œ

    https://school.programmers.co.kr/learn/courses/30/lessons/176962?language=python3# 

     

    ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

    ์ฝ”๋“œ ์ค‘์‹ฌ์˜ ๊ฐœ๋ฐœ์ž ์ฑ„์šฉ. ์Šคํƒ ๊ธฐ๋ฐ˜์˜ ํฌ์ง€์…˜ ๋งค์นญ. ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค์˜ ๊ฐœ๋ฐœ์ž ๋งž์ถคํ˜• ํ”„๋กœํ•„์„ ๋“ฑ๋กํ•˜๊ณ , ๋‚˜์™€ ๊ธฐ์ˆ  ๊ถํ•ฉ์ด ์ž˜ ๋งž๋Š” ๊ธฐ์—…๋“ค์„ ๋งค์นญ ๋ฐ›์œผ์„ธ์š”.

    programmers.co.kr

     

    ๐ŸŒฑ ํ’€์ด

    1. ๋ฌธ์ž์—ด๋กœ ๋ฐ›๋Š” ์‹œ๊ฐ„ ์ •๋ณด๋ฅผ ์ฒ˜๋ฆฌ ํ›„, ์ •๋ ฌ

    for plan in plans:
        hh, mm = plan[1].split(":")
        plan[1] = int(hh) * 60 + int(mm)
        plan[2] = int(plan[2])
    
    plans.sort(key=lambda x: x[1])

    plans์— ์‹œ์ž‘ ์‹œ๊ฐ„๊ณผ ์†Œ์š” ์‹œ๊ฐ„์ด ๋ชจ๋‘ ๋ฌธ์ž์—ด๋กœ ์ฃผ์–ด์ง€๋ฏ€๋กœ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” ๊ฒƒ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

    • ์‹œ์ž‘ ์‹œ๊ฐ„์€ "hh:mm" ํ˜•ํƒœ์ด๋ฏ€๋กœ hh * 60 + mm์œผ๋กœ ๋ฐ”๊พธ์–ด์ค๋‹ˆ๋‹ค.
    • ์†Œ์š” ์‹œ๊ฐ„์€ ์ •์ˆ˜ํ˜•์œผ๋กœ ํƒ€์ž…์„ ๋ฐ”๊พธ์–ด์ค๋‹ˆ๋‹ค.

    plans๋Š” ์‹œ๊ฐ„์ˆœ์œผ๋กœ ์ •๋ ฌ๋˜์–ด ์žˆ์ง€ ์•Š์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ •๋ ฌํ•ด์ฃผ์–ด์•ผ ํ•˜๋Š”๋ฐ, ์‹œ์ž‘ ์‹œ๊ฐ„์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌํ•˜๊ธฐ ์œ„ํ•ด sort() ๋ฉ”์„œ๋“œ์— key๋ฅผ ์ง€์ •ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

    *ํŠน์ • ์ธ๋ฑ์Šค๋ฅผ ๊ธฐ์ค€์œผ๋กœ 2์ฐจ์› ๋ฐฐ์—ด ์ •๋ ฌํ•˜๊ธฐ: array.sort(key = lambda x: x[idx])

     

    2. ์Šคํƒ์„ ์ด์šฉํ•œ ๊ตฌํ˜„

    completed_plan = []
    not_started_plan = plans
    stopped_plan = []

    ์™„๋ฃŒ๋œ ๊ณผ๋ชฉ, ์‹œ์ž‘ํ•˜์ง€ ์•Š์€ ๊ณผ๋ชฉ, ์ค‘๋‹จ๋˜ ๊ณผ๋ชฉ ๋ชจ๋‘ ์Šคํƒ์„ ์ด์šฉํ•ด์„œ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

     

    3. 

    while not_started_plan:
        name, start, playtime = not_started_plan.pop(0)
    
        # ๋งˆ์ง€๋ง‰ ๊ณผ์ œ๊ฐ€ ์•„๋‹ˆ๋ฉด
        if not_started_plan:
            next_name, next_start, next_playtime = not_started_plan[0]
    
            # ์ค‘๋‹จ
            if start + playtime > next_start:
                stopped_plan.append(
                    [name, start, playtime - (next_start - start)])
    
            else:
                complete_plans.append(name)
                remain = (next_start - start) - playtime
    
                # ๊ณผ์ œ ๋‹ค ํ•˜๊ณ ๋„ ์‹œ๊ฐ„ ๋‚จ์Œ
                while remain > 0 and stopped_plan:
                    stop_name, stop_start, stop_playtime = stopped_plan.pop(-1)
                    if stop_playtime > remain:
                        stopped_plan.append(
                            [stop_name, stop_start, stop_playtime - remain])
                    else:
                        complete_plans.append(stop_name)
                    remain -= stop_playtime
    
        else:
            complete_plans.append(name)
    • while loop์œผ๋กœ ์‹œ์ž‘ํ•˜์ง€ ์•Š์€ ๊ณผ์ œ(not_started_plan)๊ฐ€ ์—†์„ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค. 
    • ํ•ด๋‹น ๊ณผ์ œ๊ฐ€ not_started_plan์˜ ๋งˆ์ง€๋ง‰ ์›์†Œ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ๋‹ค์Œ ์›์†Œ(๊ณผ์ œ)์˜ ์‹œ์ž‘ ์‹œ๊ฐ„๊ณผ ๋น„๊ตํ•˜์—ฌ ํ˜„์žฌ ๊ณผ์ œ๋ฅผ ๋๋‚ผ ์ˆ˜ ์žˆ๋Š”์ง€, ์•„๋‹ˆ๋ฉด ์ค‘๋‹จํ•ด์•ผ ํ•˜๋Š”์ง€๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
    • ์ค‘๋‹จํ•ด์•ผ ํ•œ๋‹ค๋ฉด stopped_plan์— ํ˜„์žฌ ๊ณผ์ œ๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค. ์ด๋•Œ ์†Œ์š”์‹œ๊ฐ„์€ ์ง„ํ•ด๋œ ์‹œ๊ฐ„๋งŒํผ์„ ๋นผ์ฃผ์–ด์„œ ๋‚จ์€ ์†Œ์š” ์‹œ๊ฐ„์œผ๋กœ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.
    • ๊ณผ์ œ๋ฅผ ๋๋‚ผ ์ˆ˜ ์žˆ๋‹ค๋ฉด completed_plans์— ๊ณผ๋ชฉ ์ด๋ฆ„์„ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.
      • ๊ณผ์ œ๋ฅผ ๋๋‚ด๊ณ  ๋‚จ์€ ์‹œ๊ฐ„(remain)์„ ๊ณ„์‚ฐํ•˜์—ฌ ๋‚จ์€ ์‹œ๊ฐ„๋™์•ˆ ์ค‘๋‹จ๋œ ๊ณผ์ œ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.
      • remain์ด 0 ์ด์ƒ์ผ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•˜์—ฌ ์ค‘๋‹จ๋œ ๊ณผ์ œ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” outer loop๊ณผ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.
    • ์‹œ์ž‘ํ•˜์ง€ ์•Š์€ ๊ณผ์ œ๊ฐ€ ๋นˆ ๋ฐฐ์—ด์ด ๋˜๋ฉด ์ด์ œ ์ค‘๋‹จ๋œ ๊ณผ์ œ๋ฅผ ๋’ค์—์„œ๋ถ€ํ„ฐ ์ฐจ๋ก€๋กœ ์ˆ˜ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฆ„์„ ์ฐจ๋ก€๋กœ completed_plan์— ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

     

    ๐ŸŒฑ ์ •๋‹ต ์ฝ”๋“œ

    # !/usr/bin/env python
    # -*- coding: utf-8 -*-
    # programmers ๊ณผ์ œ ์ง„ํ–‰ํ•˜๊ธฐ
    
    def solution(plans):
        complete_plans = []
    
        for plan in plans:
            hh, mm = plan[1].split(":")
            plan[1] = int(hh) * 60 + int(mm)
            plan[2] = int(plan[2])
    
        plans.sort(key=lambda x: x[1])
    
        current_time = plans[0][1]
        not_started_plan = plans
        stopped_plan = []
    
        while not_started_plan:
            name, start, playtime = not_started_plan.pop(0)
    
            # ๋งˆ์ง€๋ง‰ ๊ณผ์ œ๊ฐ€ ์•„๋‹ˆ๋ฉด
            if not_started_plan:
                next_name, next_start, next_playtime = not_started_plan[0]
    
                # ์ค‘๋‹จ
                if start + playtime > next_start:
                    stopped_plan.append(
                        [name, start, playtime - (next_start - start)])
    
                else:
                    complete_plans.append(name)
                    remain = (next_start - start) - playtime
    
                    # ๊ณผ์ œ ๋‹ค ํ•˜๊ณ ๋„ ์‹œ๊ฐ„ ๋‚จ์Œ
                    while remain > 0 and stopped_plan:
                        stop_name, stop_start, stop_playtime = stopped_plan.pop(-1)
                        if stop_playtime > remain:
                            stopped_plan.append(
                                [stop_name, stop_start, stop_playtime - remain])
                        else:
                            complete_plans.append(stop_name)
                        remain -= stop_playtime
    
            else:
                complete_plans.append(name)
    
        while stopped_plan:
            complete_plans.append(stopped_plan.pop(-1)[0])
    
        return complete_plans
    ๋ฐ˜์‘ํ˜•

    ๋Œ“๊ธ€