지니 코딩일기

[프로그래머스] #과제 진행하기 (Python) 본문

알고리즘/코테 준비

[프로그래머스] #과제 진행하기 (Python)

zzzl 2024. 3. 5. 14:48

2024/3/4

lv2

https://school.programmers.co.kr/learn/courses/30/lessons/176962#

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

🔎 분석

처음 문제를 봤을 때, 굉장히 단순해보였다.

시간 순서대로 정렬하고, 해당 시간이 되면 시작하고, 기존 과제는 홀드 배열에 저장하고 ..

근데 문제풀이를 오랜만에 해서 그런지 문제를 제대로 읽지 않고 내맘대로 과제가 23:59까지 종료되어야만 한다고 판단해버렸다....

이것 때문에 바로 통과가 안 되어서 시간을 낭비했다.

그래도 문제를 바로 풀지 않고 손코딩을 한 뒤에 풀려고 노력했다! 앞으로는 더 꼼꼼하게 해야겠다.

 

 

✏️ 과정

1.

시간 순서대로 배열 정렬하기

plans.sort(key=lambda x:format2min(x)) # 시작시간순으로 정렬

 

2.

plans 배열을 돌면서 문제풀이를 진행하는데,

hh:mm 으로 되어 있는 시간 포맷을 모두 분(Min)으로 변환하여 보다 쉽게 시간들을 비교할 수 있도록 해야겠다고 생각했다.

=> hh:mm을 min으로 바꿔줄 format2min()함수 생성

 

3.

plans 배열 돌면서

if 현재 과제 시작시간(s_time) + 과제 수행 시간(plans[i][2]) <= 다음 과제 시작시간(plans_min[i+1]) 인 경우,

과제가 수행 완료된 것으로 보고 answer 배열에 추가한다.

또한, 수행 완료된 경우 && 다음 과제 시작 전 이라면 hold 배열의 과제를 수행할 수 있으므로,

hold 배열의 가장 마지막 값부터 pop을 하여 수행해준다.

else 인 경우,

남은 시간(l_time) = (현재 과제 시작시간 + 과제 수행시간) - 다음 과제 시작시간,

과제가 완료되지 않았으므로, 수행하고 남은 시간을 hold 배열에 추가한다.

 

4.

마지막 과제의 경우에는, 다음 과제 시작시간이 없으므로 무조건 바로 수행 완료된다.

(따로 처리해준다)

 

 

📍TIP

plans 배열의 for문을 돌면서 현재, 다음 과제의 시작 시간 값을 계속 사용하므로,

중복으로 구하는 연산을 피하기 위해 plans_min 배열에 저장하여 사용하도록 하였다.

 

💻 코드

def format2min(plan):
    hour_min = plan[1].split(':')
    return int(hour_min[0])*60 + int(hour_min[1])
    
def solution(plans):
    answer = []
    holds = []
    plans_min = [0 for _ in range(len(plans))]
    
    plans.sort(key=lambda x:format2min(x)) # 시작시간순으로 정렬
    
    now = 0
    s_time = format2min(plans[0])
    plans_min[0] = s_time
    for i in range(len(plans)):
        s_time = plans_min[i]
        
        if i==len(plans)-1:
            # 마지막 과제
            answer.append(plans[-1][0])
            for _ in range(len(holds)):
                hold = holds.pop()
                answer.append(hold[0])
            break
        
        plans_min[i+1] = format2min(plans[i+1])
        if s_time + int(plans[i][2]) <= plans_min[i+1]:     
            answer.append(plans[i][0]) # 종료된 과제
            now = s_time + int(plans[i][2])
            while len(holds)>0:
                hold = holds.pop()
                if now + hold[1] <= plans_min[i+1]:
                    answer.append(hold[0])
                    now = now+hold[1]
                else:
                    holds.append([hold[0], now + hold[1] - plans_min[i+1]])
                    break
                
                
                
        else:
            l_time = (s_time + int(plans[i][2])) - plans_min[i+1]
            holds.append([plans[i][0], l_time]) # 홀드된 과제
    
    

    return answer