본문 바로가기

컴린이 일기장/Today I Learned

[TIL] 프로그래머스 - 다리를 지나는 트럭 / 프로그래머스 - 프린터

반응형

[Today I Learned]

# 프로그래머스 - 다리를 지나는 트럭

문제 설명
트럭 여러 대가 강을 가로지르는 일차선 다리를 정해진 순으로 건너려 합니다. 모든 트럭이 다리를 건너려면 최소 몇 초가 걸리는지 알아내야 합니다. 다리에는 트럭이 최대 bridge_length대 올라갈 수 있으며, 다리는 weight 이하까지의 무게를 견딜 수 있습니다. 단, 다리에 완전히 오르지 않은 트럭의 무게는 무시합니다.예를 들어, 트럭 2대가 올라갈 수 있고 무게를 10kg까지 견디는 다리가 있습니다. 무게가 [7, 4, 5, 6]kg인 트럭이 순서대로 최단 시간 안에 다리를 건너려면 다음과 같이 건너야 합니다.

 

@solution.py

문제를 잘 읽자! 다리를 '정해진 순'으로 건너는건데 내가 최적의 순까지 찾아야하는 건 줄 알고 고민했다. 예시 이해하는게 조금 헷갈려서 질문하기를 봤는데 1초에 1칸 전진한다는 내용이 빠져있는 것 같더라 ㅎㅎ;

def solution(bridge_length, weight, truck_weights):
    
    time = 0
    bridge = []
    
    while truck_weights or bridge:

        time += 1

        bridge = [[b[0],b[1]+1] for b in bridge if b[1]+1<bridge_length]

        if truck_weights:
            if sum([b[0] for b in bridge]) + truck_weights[0] <= weight:
                bridge.append([truck_weights.pop(0), 0])  

    return time

손으로 매뉴얼하게 푸는 방법은 쉽게 생각했는데, 코드로 바꾸는 과정이 어려웠다. 어떤 케이스에서든 일관적으로 적용되는 규칙을 찾자! 또 time += 1을 어느 시점에 할 것인지, 트럭이 다리 어디에 있는지 위치를 어떻게 표현할 것인지 등을 내가 가장 잘 이해한대로 두어서, 구현에 드는 시간을 줄여보자. :)

채점에서 시간 초과가 나지는 않았지만, sum을 구하기 위해서 반복문을 계속 사용하는 점이 아쉬웠는데, 매번 list comprehension으로 구할게 아니라 따로 변수를 두면 될 것 같다. 

 

# 프로그래머스 - 프린터

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

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 함수를 작성해주세요.

 

@solution.py

def solution(priorities, location):
    
    queue = [[i,p] for i, p in enumerate(priorities)]
    ps = sorted(priorities)
    count = 0
    
    while queue:
        if queue[0][1] != ps[-1]:
            queue.append(queue.pop(0))
        else:
            count += 1
            ps.pop()
            print = queue.pop(0)
            
            if print[0] == location:
                break

    return count

디버깅도 안했는데 첫 트에 바로 통과해서 기분 좋았던 문제. priorities를 sort한 ps를 따로 두어서, 매번 현재 queue의 중요도 max 값이 무엇인지 찾지 않도록 했다. 일부러 reverse도 안넣어서 pop(0)을 쓰지 않게했다. (알린이 나름의 노력,,)

다른 사람들 풀이에 좋은 내용, 낯선 내용 등이 있어서 간단히 정리해보았다.

# 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
- 하나라도 True인게 있으면 True를 반환
+ all()은 모두 True여야 True를 반환한다.

 

# for - else
def solution(priorities, location):
    answer = 0
    search, c = sorted(priorities, reverse=True), 0
    while True:
        for i, priority in enumerate(priorities):
            s = search[c]
            if priority == s:
                c += 1
                answer += 1
                if i == location:
                    break
        else:
            continue
        break
    return answer

for - else
- for문이 break 등으로 중간에 빠져나오지 않고 끝까지 실행되었을 경우 else문이 실행됨

for i in range(5):
    print(i, end=' ')
else:
    print("for문이 끝까지 실행되었습니다!")
 
 
for i in range(5):
    if i == 2:
        break
    print(i, end=' ')
else:
    print("for문이 끝까지 실행되었습니다!")

^ 실행결과

 

반응형