프린터의 동작이 선입선출(FIFO) 구조를 띄는 큐와 똑같았기 때문에 큐로 풀고자 했다. 여기서 location이 주어지기 때문에 처음 인덱스 값을 기억하고 있어야 했다.(왜냐면 큐 동작을 수행하다보면 위치가 바뀌니까)
처음 풀이에는 enumerate을 생각 못하고 location이 바뀌는 것을 일일이 조건식으로 제어했다.
def solution(priorities, location):
answer = 0
while priorities:
if priorities[0] == max(priorities): # 대기목록의 가장 앞에 있는 문서가 우선순위도 가장 높을 경우
priorities.pop(0)
answer += 1
if location == 0:
return answer
else:
location -= 1
else: # 대기목록의 앞에 있는 원소가 우선순위가 낮을 경우
priorities.append(priorities.pop(0))
if location == 0:
location = len(priorities) - 1
else:
location -= 1
return answer
이렇게 짜도 통과는 했지만 가독성도 안좋고, 조건식이 많아서 실수가 나오기 좋을 것 같았다. 아래는 다른 사람이 사용한 enumerate을 보고 다시 작성해본 코드
def solution(priorities, location):
answer = 0
queue = [(v,i) for i, v in enumerate(priorities)]
while queue :
this = queue.pop(0)
if queue and this[0] < max(queue)[0] :
queue.append(this)
else :
answer += 1
if this[1] == location:
break
return answer
enumerate을 통해 (우선순위, index(=location)) 형태의 튜플을 담은 큐로 만들었다. 한 가지 주의할 점은 max(), min(), avg() 등은 리스트가 비어있으면 에러가 나기 때문에 삭제 연산 등 리스트의 길이에 변동이 있다면 조건에 같이 넣어줘야 한다.
def solution(priorities, location):
answer = 0
from collections import deque
d = deque([(v,i) for i,v in enumerate(priorities)])
while len(d):
item = d.popleft()
if d and max(d)[0] > item[0]:
d.append(item)
else:
answer += 1
if item[1] == location:
break
return answer
덱을 이용해서 푼 풀이. 나는 결과적으로 큐라는 자료구조를 이용해서 파이썬 리스트로 풀이했는데 이는 time complexity 문제가 발생할 수 있었다. 덱의 popleft()의 time complexity는 O(1)인 반면 pop(0)의 time complexity는 O(N)이기 때문에 시간이 오래 걸린다.
순서가 있는 자료형(리스트, 튜플, 문자열)을 입력으로 받아 인덱스 값을 포함하는 enumerate 객체 반환
for문처럼 반복되는 구간에서 객체가 현재 어느 위치에 있는지 알려주는 인덱스 값이 필요할때 enumerate 함수를 사용하면 유용
인덱스(index)와 원소를 동시에 접근하면서 루프
>>> for entry in enumerate(['A', 'B', 'C']):
... print(entry)
...
(0, 'A')
(1, 'B')
(2, 'C')
enumerate() 함수를 호출할 때 start 인자에 시작하고 싶은 숫자 할당
>>> for i, letter in enumerate(['A', 'B', 'C'], start=1):
... print(i, letter)
...
1 A
2 B
3 C
index를 기준으로 출력하는 것이 아니라 value가 먼저 나오게 출력. 생각보다 자주 쓰이니까 숙지하자. 또 이렇게 리스트 안에 묶어서 한줄로 출력할 수 있다.
[(v,i) for i,v in enumerate(priorities)]