[프로그래머스] Lv.2 프린터 (Python)

seulzzang·2022년 11월 4일
0

코딩테스트 연습

목록 보기
37/44

📍문제

[프로그래머스] Lv.2 프린터

📍풀이

💻첫번째 코드(통과, 큐 사용X)

def solution(priorities, location):
    answer = 0
    while True:
        max_priority = max(priorities)
        for i in range(len(priorities)):
            if priorities[i] == max_priority:
                answer += 1
                priorities[i] = 0 # 출력 됨
                max_priority = max(priorities) # 최대값 갱신
                if i == location: # location과 동일한 인덱스가 나오면
                    return answer
    return answer

출력된 문서의 priorities를 0으로 바꿔주고 최대값을 갱신해주기를 반복한다. 그러다 location과 같은 인덱스가 나오면 answer를 출력해주는 방식이다.

이 문제의 카테고리가 스택/큐라서 큐로 풀어보기로 하고 코드를 다시 짜봤다.

💻두번째 코드(통과, 큐 사용)

from collections import deque

def solution(priorities, location):
    answer = 0
    lst = [[index, pri] for index, pri in enumerate(priorities)]
    doc_index = deque([index[0] for index in lst])
    doc_pri = deque([index[1] for index in lst])
    
    while doc_index and doc_pri:
        current_doc = doc_index.popleft() # 현재 문서
        current_pri = doc_pri.popleft() # 현재 문서의 중요도
        if len(doc_index) == 0:
            answer += 1
            break
        if current_pri < max(doc_pri): # 최대값보다 작으면
            doc_index.append(current_doc) # 뒤로 붙여줌
            doc_pri.append(current_pri) # 뒤로 붙여줌
        else:
            answer += 1
            if current_doc == location:
                break
            
    return answer

문제 그대로를 구현한 코드이다.
현재 문서와 현재 문서의 중요도를 popleft()로 꺼내주고, 만약 이 값이 중요도의 최대값보다 작으면 뒤로 붙여준다. 만약, 현재 문서의 중요도가 중요도의 최대값보다 크다면 중요도가 베스트여서 인쇄를 한 것이니 answer += 1을 해주고, 그 때 현재 문서의 번호가 location과 동일하다면 반복문을 빠져나온다.
여기서 프린터에 문서가 단 한개 존재할 경우, current_doc = doc_index.popleft()를 진행하는 경우 빈 큐가 되기 때문에 이후 코드를 진행할 수 없어 런타임 에러가 뜬다. 따라서 if문 조건을 추가해줘야 한다.

📍다른사람 풀이

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(), all()

  • iteralbe한 객체를 받아 이 객체를 돌면서 조건을 검사해 답을 True/Flase의 boolean 형태로 반환한다.

    any(): 하나라도 True인게 있으면 True
    all(): 모두 True여야 True 반환

if any(cur[1] < q[1] for q in queue):
            queue.append(cur)

현재 문서의 중요도보다 더 큰 중요도가 1개라도 존재하면 현재 문서를 뒤로 보낸다는 뜻이다.

이렇게 하면 굳이 max를 사용하지 않아도 된다! 리스트 내에 해당 수 보다 큰 수가 있기만 하면 바로 True를 리턴하기 때문에 시간이 덜 걸린다.
이 코드에서 pop(0)을 사용하지 않고 dequepopleft()를 사용한다면 조금 더 시간복잡도부분에서 개선될 것 같다.

profile
중요한 것은 꺾이지 않는 마음

0개의 댓글