[프로그래머스] LV.2 과제 진행하기

정재욱·2023년 4월 9일
0

Algorithm

목록 보기
14/33
post-thumbnail

프로그래머스 LV.2 과제 진행하기

문제

과제를 받은 루는 다음과 같은 순서대로 과제를 하려고 계획을 세웠습니다.

  • 과제는 시작하기로 한 시각이 되면 시작합니다.
  • 새로운 과제를 시작할 시각이 되었을 때, 기존에 진행 중이던 과제가 있다면 진행 중이던 과제를 멈추고 새로운 과제를 시작합니다.
  • 진행중이던 과제를 끝냈을 때, 잠시 멈춘 과제가 있다면, 멈춰둔 과제를 이어서 진행합니다.
    만약, 과제를 끝낸 시각에 새로 시작해야 되는 과제와 잠시 멈춰둔 과제가 모두 있다면, 새로 시작해야 하는 과제부터 진행합니다.
  • 멈춰둔 과제가 여러 개일 경우, 가장 최근에 멈춘 과제부터 시작합니다.

과제 계획을 담은 이차원 문자열 배열 plans가 매개변수로 주어질 때, 과제를 끝낸 순서대로 이름을 배열에 담아 return 하는 solution 함수를 완성해주세요.


문제 풀이

  1. 내 풀이
    우선 입력데이터를 시작시간, 종료시간에 맞춰 새로 계산해주고 오름차순 정렬을 해준다.
    중단된 과제를 저장항 리스트인 stop_subject를 생성해준다.
    현재 과제에 대한 정보를 subject, start, end에 저장해주고 반복문을 통해 다음 과제에 대한 조사를 한다.
    • 만약 지금 과제(subject, start, end)가 끝나기 전에 다음 과제를 시작해야 된다면
      • stop_subject에 지금 과제 저장
      • subject, start, end를 다음 과제로 최신화
    • 만약 다음 과제가 시작하기 전에 지금 과제가 끝난다면
      • 지금 과제를 끝내고 (answer에 넣고)
      • 공강시간 계산
        • 공강시간만큼 중단했던 과제들 처리
      • 이후 subject, start, end를 다음 과제로 최신화
    • 만약 다음 과제가 시작하는 시간이 지금 과제가 끝나는 시간과 같다면
      • 지금 과제를 끝내고 (answer에 넣고)
      • 이후 subject, start, end를 다음 과제로 최신화
def solution(plans):
    answer = []
    for idx in range(len(plans)):
        hour, min = map(int,plans[idx][1].split(":"))
        start = hour * 60 + min
        end = start + int(plans[idx][2])
        plans[idx][1], plans[idx][2] = start, end
        
    plans.sort(key = lambda x:(x[1], x[2]))
    stop_subject = []
    
    subject, start, end = plans[0]
    
    for i in range(1, len(plans)):
        if plans[i][1] < end:
            # 지금 과제가 끝나기 전에 다음 과제를 시작해야 된다면
            stop_subject.append([subject, end-plans[i][1]]) # 리스트에 지금 과제 저장
            subject, start, end = plans[i] # 과제 최신화
            
        elif plans[i][1] > end: # 다음 과제가 시작하기 전에 지금 과제가 끝난다면
            answer.append(subject) # 지금 과제를 끝내고
            empty_time = plans[i][1] - end  # 공강시간 계산
            
            while stop_subject and empty_time > 0: # 공강시간만큼 중단했던 과제들 처리
                if empty_time >= stop_subject[-1][1]:
                    a,b = stop_subject.pop()
                    answer.append(a)
                    empty_time -= b
                else:
                    stop_subject[-1][1] -= empty_time
                    break
            subject, start, end = plans[i] # 다음 과제로 최신화

        else: # plans[i][1] == end
            answer.append(subject)
            subject, start, end = plans[i]

            
    answer.append(subject)
    for i in range(len(stop_subject)-1,-1,-1):
        answer.append(stop_subject[i][0])
            
    return answer

  1. 더 좋은 풀이
def solution(plans):
    plans = sorted(map(lambda x: [x[0], int(x[1][:2]) * 60 + int(x[1][3:]), int(x[2])], plans), key=lambda x: -x[1])
    # 시작 시간 기준 내림차순
    
    lst = [] # 과제들이 각각 끝나는 시간을 담을 리스트
    while plans:
        x = plans.pop() # 가장 빠른 시작시간의 과제 
        for i, v in enumerate(lst):
            if v[0] > x[1]: # 만약 먼저 시작했던 과제의 끝나는 시간이, 지금 과제의 시작시간보다 크다면 
                lst[i][0] += x[2] # 먼저 시작한 과제들은 지금 과제가 끝날 때 까지 걸리는 시간만큼 더 늦게 끝나니까 
        lst.append([x[1] + x[2], x[0]]) # 이후 리스트에 현재 과제의 종료시간 추가
    lst.sort() # 오름차순 정렬

    return list(map(lambda x: x[1], lst)) # 과제 이름만 출력
profile
AI 서비스 엔지니어를 목표로 공부하고 있습니다.

0개의 댓글