https://school.programmers.co.kr/learn/courses/30/lessons/176962
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
시간 순서에 맞춰 과제를 진행하되, 새로운 과제를 시작할 시간이 된다면, 진행중인 과제를 잠시 중단하고 새로운 과제를 시작한다.
현재 과제 완료 후 멈춰둔 과제가 있다면, 마지막으로 멈춘 과제부터 마저 진행하되, 과제 진행 우선 순서는 새로운 과제가 우선이다.
1. 접근
보통 일정과 관련된 문제들은 heap 을 활용하여 진행하는 것이 개인적으로 편해서 heap 을 사용하기로 했고
이 문제의 경우, 멈춰둔 과제를 진행하는 작업이 몇 번이나 반복될지 모르기 때문에 남은 작업 시간을 지속적으로 갱신해야 할 필요가 있다.
2. 전처리
일반적으로 일정 관련된 문제가 나오는 경우 int 형식으로 주어지는 문제로 자주 접했으나
이 문제의 경우 시간을 문자열로 입력이 된다. 이 부분을 처리하기 쉽도록 정리해야한다.
또, 과제 정보 (시작 시간, 이름, 완료에 소요되는 시간) 가 시간 순서대로 주어지지 않으므로 정렬이 필요하다.
def solution(plans):
answer = []
works = []
plans.sort(key=lambda x:x[1], reverse=True)
new_plans = []
index = 1
for name, start, resource in plans:
hour, minute = map(int, start.split(":"))
adjust_time = hour * 60 + minute
new_plans.append([index, adjust_time, int(resource), name])
index += 1
먼저 가장 빠른 시간 순으로 처리하기 위해 주어진 plans 리스트를 시간 역순으로 정렬했다.
그 다음으로 시간 정보를 int 형으로 변경하여 계산이 쉽도록 해야했는데,
문제에서 시간은 00:00 ~ 23:59로 날짜를 넘기는 경우가 발생하지 않으므로, 분을 기준으로 통일하기 위해
주어진 시간 정보를 모두 분으로 변경했다. (시간 * 60 + 분)
그 다음, 미뤄진 문제에 대한 우선순위를 정하기 위해 가장 늦은 시간 > 빠른 시간 과제 순으로 index를 넣어줬다
(1, 2 번 과제가 미뤄지면 우선순위는 2번에 있으므로 역순으로 index 부여)
3. 처리
while new_plans:
idx, now, resource, name = new_plans.pop()
if new_plans and new_plans[-1][1] < now + resource:
resource -= (new_plans[-1][1] - now)
heapq.heappush(works, [idx, resource, name])
else:
answer.append(name)
complete_time = now + resource
while works and new_plans:
idx, resource, name = heapq.heappop(works)
if complete_time + resource <= new_plans[-1][1]:
answer.append(name)
complete_time += resource
else:
resource -= (new_plans[-1][1] - complete_time)
heapq.heappush(works, [idx, resource, name])
break
while works:
idx, remain_resource, name = heapq.heappop(works)
answer.append(name)
new_plans 에서 데이터를 하나씩 뽑아
1. 시작시간 + 소요시간이 다음 과제의 시작 시간보다 늦지 않는다면
> answer 에 추가 / 현재 시간 = 과제 시작 시간 + 소요 시간
1-1. works 와 new_plans 모두 데이터가 남아있고,
works 리스트 인덱스 0번의 ( 소요 시간 + 현재 시간 )이 다음 과제 시작 시간보다 늦지 않는다면
> answer 에 추가 / 1.의 현재 시간 += 소요 시간
1-2. works 와 new_plans 모두 데이터가 남아있고,
works 리스트 인덱스 0번의 ( 소요 시간 + 현재 시간 )이 다음 과제 시작 시간보다 늦지는다면
> ( 다음 과제 시작 시간 - 1.의 현재 시간 ) 만큼 소요 시간에서 차감 후 works 에 추가
2. 시작 시간 + 소요시간이 다음 과제의 시작 시간보다 늦는다면
> works 에 추가하되, ( 다음 과제 시작 시간 - 현재 과제 시작 ) 만큼 소요 시간에서 차감
3. works 가 남아있다면, 순서대로 뽑아서 answer에 추가
4. 최종 코드
import heapq
def solution(plans):
answer = []
works = []
plans.sort(key=lambda x:x[1], reverse=True)
new_plans = []
index = 1
for name, start, resource in plans:
hour, minute = map(int, start.split(":"))
adjust_time = hour * 60 + minute
new_plans.append([index, adjust_time, int(resource), name])
index += 1
while new_plans:
idx, now, resource, name = new_plans.pop()
if new_plans and new_plans[-1][1] < now + resource:
resource -= (new_plans[-1][1] - now)
heapq.heappush(works, [idx, resource, name])
else:
answer.append(name)
complete_time = now + resource
while works and new_plans:
idx, resource, name = heapq.heappop(works)
if complete_time + resource <= new_plans[-1][1]:
answer.append(name)
complete_time += resource
else:
resource -= (new_plans[-1][1] - complete_time)
heapq.heappush(works, [idx, resource, name])
break
while works:
idx, remain_resource, name = heapq.heappop(works)
answer.append(name)
return answer
'Algorithm > 프로그래머스' 카테고리의 다른 글
[프로그래머스] PCCP 기출문제 2번 (1) | 2023.11.28 |
---|---|
[프로그래머스] 혼자서 하는 틱택토 (1) | 2023.11.22 |
[프로그래머스] 피로도 (0) | 2023.11.17 |
[프로그래머스] 숫자 블록 (0) | 2023.11.15 |