[프로그래머스][스택/큐] 프린터

sewonK·2021년 7월 27일
0

내가 푼 풀이

from collections import deque
def solution(priorities, location):
    answer = 0
    order = deque([])
    results = []
    for i in range(0, len(priorities)):
        order.append([i, priorities[i]])
    
    while order:
        Print = True
        cur = order[0]
        for i in order:
            if (cur[1] < i[1]):
                #나머지 인쇄 대기목록에서 J보다 중요도가 높은 문서가 한 개라도 존재하면 J를 대기목록의 가장 마지막에 넣습니다.
                order.popleft()
                order.append(cur) 
                Print = False
                break                   
        if (Print): #대기열에 J를 넣지 않았으면 J를 인쇄
            results.append(cur)
            order.popleft()

    for result in results:
        answer += 1
        if (location == result[0]):
            break
    return answer

처음에 문제 이해를 잘 못해서 약간 애먹었던 문제다.

1. 인쇄 대기목록의 가장 앞에 있는 문서(J)를 대기목록에서 꺼냅니다.
2. 나머지 인쇄 대기목록에서 J보다 중요도가 높은 문서가 한 개라도 존재하면 J를 대기목록의 가장 마지막에 넣습니다.
3. 그렇지 않으면 J를 인쇄합니다.

사실상 여기 쓰여있는 그대로만 구현하면 되는 문제인데, 하나를 인쇄하면 끝인줄알고 그렇게 구현했다가 폭풍 실패를 맛보고 문제를 다시읽었다.

나는 while문 안에 for문을 넣었는데, 별로 좋은 방법 같지는 않다. 최대 대기목록이 100개라서 다행이지, 1만 개 이상일 경우에는 무조건 시간 초과가 날 것 같은 코드이기 때문이다. 근데 이 문제에서는 이 방법 외에 떠오르는 방법이 없었다.

내 방법은 정말 저기 말 그대로 구현한 것이다. 대기목록이 전부 인쇄되어 없어질 때까지 대기목록에 넣고, 인쇄하고를 반복한다.

c++에서 구현되어있는 pop()은 python에서는 popleft()로 사용이 가능하다. 그냥 pop()은 stack처럼 맨 마지막 element를 pop하는 함수이다.

번외, enumerate

for문을 사용할 때, 몇 번 돌았는지 counting을 하고싶은데 변수를 선언하는 방법밖에 없나? 불편했었다.
enumerate함수를 사용하면 for문에서 count idx를 구할 수 있다.

for idx,item in enumerate(list):

출처) https://stackoverflow.com/questions/3162271/get-loop-count-inside-a-python-for-loop

위와 같이 사용하면, list 내 item도 꺼내면서 idx까지 구할 수 있다.

(예제)

list = ['a', 'b', 'c', 'd']
for idx, item in enumerate(list):
    print(idx, item)
>>> 0 a
>>> 1 b
>>> 2 c
>>> 3 d

이를 이용하면 위의 문제 중

for i in range(0, len(priorities)):
    order.append([i, priorities[i]])

이 부분을

 order =  [(i,p) for i,p in enumerate(priorities)]

로 깔끔하게 고칠 수 있다.

Any

Best 풀이의 경우 Any 함수를 썼다.

def solution(priorities, location):
    queue =  [(i,p) for i,p in enumerate(priorities)]
    answer = 0
    while True:
        cur = queue.pop(0)
        if any(cur[1] < q[1] for q in queue):
            queue.append(cur)
        else:
            answer += 1
            if cur[0] == location:
                return answer

왜 같은 파이썬인데 나만 코드 길어..

any(iterableValue) 함수는 전달받은 자료형의 element 중 하나라도 True일 경우 True를 돌려준다.
위의 코드로 보면, queue 내에 cur[1] < q[1]인 q가 하나라도 있으면 True를 돌려준다는 것이다(for문으로 돌 필요가 없다는 의미, 시간 복잡도는 O(N)으로 같을 거라 예상되지만 보기에 더 예쁘니까!).

0개의 댓글