조금씩 꾸준히 완성을 향해

[Programmers] 프로그래머스 프린터 with Python 본문

DataStructure & Algorithm/문제풀이

[Programmers] 프로그래머스 프린터 with Python

all_sound 2022. 10. 11. 23:47

문제 설명

일반적인 프린터는 인쇄 요청이 들어온 순서대로 인쇄합니다. 그렇기 때문에 중요한 문서가 나중에 인쇄될 수 있습니다. 이런 문제를 보완하기 위해 중요도가 높은 문서를 먼저 인쇄하는 프린터를 개발했습니다. 이 새롭게 개발한 프린터는 아래와 같은 방식으로 인쇄 작업을 수행합니다.

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

예를 들어, 4개의 문서(A, B, C, D)가 순서대로 인쇄 대기목록에 있고 중요도가 2 1 3 2 라면 C D A B 순으로 인쇄하게 됩니다.

내가 인쇄를 요청한 문서가 몇 번째로 인쇄되는지 알고 싶습니다. 위의 예에서 C는 1번째로, A는 3번째로 인쇄됩니다.

현재 대기목록에 있는 문서의 중요도가 순서대로 담긴 배열 priorities와 내가 인쇄를 요청한 문서가 현재 대기목록의 어떤 위치에 있는지를 알려주는 location이 매개변수로 주어질 때, 내가 인쇄를 요청한 문서가 몇 번째로 인쇄되는지 return 하도록 solution 함수를 작성해주세요.

제한사항
  • 현재 대기목록에는 1개 이상 100개 이하의 문서가 있습니다.
  • 인쇄 작업의 중요도는 1~9로 표현하며 숫자가 클수록 중요하다는 뜻입니다.
  • location은 0 이상 (현재 대기목록에 있는 작업 수 - 1) 이하의 값을 가지며 대기목록의 가장 앞에 있으면 0, 두 번째에 있으면 1로 표현합니다.
입출력 예
priorities location return
[2, 1, 3, 2] 2 1
[1, 1, 9, 1, 1, 1] 0 5

내가 짠 코드

from collections import deque  #deque 라이브러리 import
def solution(priorities, location):
    Q = deque()  #deque 객체 생성
    answer = 0  #카운트할 결과값 초기화
    for idx, prio in enumerate(priorities): #입력 리스트의 인덱스와 value를 튜플형태로 Q에 저장
        Q.append((idx, prio))
    while Q:   # Q가 존재할 때까지 while문 반복      
        pl = Q.popleft()  
        if any(pl[1] < x[1] for x in Q): #가장 앞에서 빼낸 값이 최우선순위가 아니면
            Q.append(pl)  # Q 뒤에 삽입
        else:  #가장 앞에서 빼낸 값이 최우선순위라면
            answer += 1  #결과에 카운트 1씩 쌓기
            if pl[0] == location: #만약 빼낸 값이 입력받은 위치값과 같다면
                return answer  #결과를 반환 후 break
                break

사실 100% 내가 짰다고 할 수는 없는 코드이지만, 지금은 내가 짤 수 있게 된 코드이다.

비슷한 예제를 한 번 눈으로 봐 둔 적은 있었지만 정확히 기억은 안나는 상태에서 문제에 도전했다.

any 라는 문법을 쓰면 쉽게 구현이 가능하다는 걸 알아서 슬쩍 검색 후 완성을 했다. 다음 날 또 다시 짜봤을 때도 구현이 가능해서 잘 기억한 것으로 간주했다.

 

이 문제에서 내가 많이 고민했던 부분 두 가지가 enumerate와 any이다. 인쇄를 요청한 문서가 몇 번째로 인쇄되는지를 구해야 하기 때문에 뭔가 인덱싱을 할 수단이 필요하다고 생각했는데, enumerate로 간단히 해결되었다. 자주 쓰지 않으면 바로바로 떠오르지 않는 구문이라 많이 반복해야 할 것 같다. 

그리고 any() 라는 문법은 괄호 안의 구문에 True가  하나라도 존재하면 True를 반환한다. 반대 개념으로 all()은 괄호 안의 구문이 모두 True일 경우 True를 반환한다. 이번 문제처럼 많은 조건을 검사해야 할 경우 매우 유용하게 쓰일 것 같다.

 

 

 

다른 코드 참고

from collections import deque
def solution(priorities, location):
    answer = 0
    Q = deque([(v,i) for i, v in enumerate(priorities)])
    while Q:
        pl = Q.popleft()
        if pl[0] < max(Q)[0] :
            Q.append(pl)
        else:
            answer +=1
            if pl[1] == location:
                break
    return answer

any를 쓰지 않고 신박하게 짠 코드가 있어서 가져와 보았다.

우선순위 비교를 할 때 Q의 max값을 사용한 부분이 눈에 띈다. Q에 들어있는 아이템은 튜플형태이기 때문에 max는 첫번째 값 기준으로 계산된다. 따라서 Q를 생성할 때 (index, value) 가 아니라 (value, index) 순서로 집어 넣은 걸 알 수 있다. 아주 좋은 아이디어라고 생각했다. 

 

 

https://school.programmers.co.kr/learn/courses/30/lessons/42587

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr