ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 배달
    코딩 테스트/Level 3 2020. 10. 12. 14:48
    반응형

    배달
    Summer/Winter Coding(~2018) 
    768명 완료

    https://programmers.co.kr/learn/courses/30/lessons/12978

     

    코딩테스트 연습 - 배달

    5 [[1,2,1],[2,3,3],[5,2,2],[1,4,2],[5,3,1],[5,4,2]] 3 4 6 [[1,2,1],[1,3,2],[2,3,2],[3,4,3],[3,5,2],[3,5,3],[5,6,1]] 4 4

    programmers.co.kr

    다익스트라 알고리듬을 이용하는 거 같은데.. 
    다익스트라 알고리듬이 기억이 안 난다 ㅠ,.ㅠ

    일단 생각의 흐름을 따라 코딩했다..

    테스트 케이스는 통과가 되지만...
    당연히 순서가 꼬이면... 엉망인 답이 나온다..

    문제는 순서~!

    def solution(n, road, k):
        distances = {1: 0}
        for index, (a, b, length) in enumerate(road):
            distances[b] = min(distances.get(a, float('inf')) + length, distances.get(b, float('inf')))
            distances[a] = min(distances[b] + length, distances.get(a, float('inf')))
            # print(distances)
        return len([1 for a in distances.values() if a <= k])
    
    
    print(solution(5, [[1, 2, 1], [2, 3, 3], [5, 2, 2], [1, 4, 2], [5, 3, 1], [5, 4, 2]], 3))
    print(solution(5, [[2, 3, 3], [5, 2, 2], [1, 4, 2], [5, 3, 1], [5, 4, 2], [1, 2, 1]], 3))
    {1: 0, 2: 1}
    {1: 0, 2: 1, 3: 4}
    {1: 0, 2: 1, 3: 4, 5: 3}
    {1: 0, 2: 1, 3: 4, 5: 3, 4: 2}
    {1: 0, 2: 1, 3: 4, 5: 3, 4: 2}
    {1: 0, 2: 1, 3: 4, 5: 3, 4: 2}
    4
    {1: 0, 3: 2000, 2: 2000}
    {1: 0, 3: 2000, 2: 2000, 5: 2000}
    {1: 0, 3: 2000, 2: 2000, 5: 2000, 4: 2}
    {1: 0, 3: 2000, 2: 2000, 5: 2000, 4: 2}
    {1: 0, 3: 2000, 2: 2000, 5: 4, 4: 2}
    {1: 0, 3: 2000, 2: 1, 5: 4, 4: 2}
    3

    다익스트라가 가까운 노드부터 탐색하던 개념이던가...
    예전에 책에서 본 적 있는데...

    알고리듬 책은 Hello Coding 그림으로 개념을 이해하는 알고리즘 - 아디트야 바르가바 추천. 
    고등학교 때 퀵 정렬 공부한 이후로 전혀 알고리듬을 공부하지 않았던 아재 취미 코더에게도 어렵지 않았다...
    (뒷광고 아님, 리뷰용 책 한 권 받아본 적 없음.)

    def solution(n, road, k):
        graph = {}
        for a, b, cost in road:
            graph[a] = graph.get(a, set()).union({(b, cost)})
            graph[b] = graph.get(b, set()).union({(a, cost)})
        distances = {1: 0}
        while graph:
            node, min_val = None, float('inf')
            for key in distances:
                if key in graph and distances[key] < min_val:
                    node, min_val = key, distances[key]
            for neighbor, cost in graph[node]:
                if neighbor in graph:
                    distances[neighbor] = min(distances[node] + cost, distances.get(neighbor, float('inf')))
            del graph[node]
        return sum(1 for a in distances.values() if a <= k)
    테스트 1 〉	통과 (0.07ms, 10.9MB)
    테스트 2 〉	통과 (0.06ms, 10.7MB)
    테스트 3 〉	통과 (0.07ms, 10.8MB)
    테스트 4 〉	통과 (0.08ms, 10.7MB)
    테스트 5 〉	통과 (0.09ms, 10.8MB)
    테스트 6 〉	통과 (0.05ms, 10.7MB)
    테스트 7 〉	통과 (0.07ms, 10.8MB)
    테스트 8 〉	통과 (0.06ms, 10.8MB)
    테스트 9 〉	통과 (0.06ms, 10.9MB)
    테스트 10 〉	통과 (0.07ms, 10.8MB)
    테스트 11 〉	통과 (0.07ms, 10.8MB)
    테스트 12 〉	통과 (0.17ms, 10.7MB)
    테스트 13 〉	통과 (0.12ms, 10.7MB)
    테스트 14 〉	통과 (3.02ms, 11.2MB)
    테스트 15 〉	통과 (4.55ms, 11.6MB)
    테스트 16 〉	통과 (0.09ms, 10.8MB)
    테스트 17 〉	통과 (0.12ms, 10.8MB)
    테스트 18 〉	통과 (0.69ms, 10.9MB)
    테스트 19 〉	통과 (3.46ms, 11.5MB)
    테스트 20 〉	통과 (0.62ms, 10.8MB)
    테스트 21 〉	통과 (5.58ms, 12.4MB)
    테스트 22 〉	통과 (0.91ms, 10.9MB)
    테스트 23 〉	통과 (4.82ms, 12MB)
    테스트 24 〉	통과 (2.97ms, 11.4MB)
    테스트 25 〉	통과 (7.16ms, 13.3MB)
    테스트 26 〉	통과 (6.91ms, 13.3MB)
    테스트 27 〉	통과 (7.17ms, 13.5MB)
    테스트 28 〉	통과 (7.55ms, 13.6MB)
    테스트 29 〉	통과 (7.29ms, 13.5MB)
    테스트 30 〉	통과 (5.63ms, 13.5MB)
    테스트 31 〉	통과 (0.18ms, 10.8MB)
    테스트 32 〉	통과 (0.25ms, 10.8MB)

    생각의 흐름에 따라 코딩했더니..
    일반적인 다익스트라 스타일과 좀 다른 느낌이라..

    공부 차원에서...
    일반적인 다익스트라 스타일도...
    찾아서 코딩해 보았다...

    def solution(N, road, K):
        from queue import PriorityQueue
        distances = [float('inf') for _ in range(N + 1)]
        distances[1] = 0
        que = PriorityQueue()
        que.put((0, 1))
        while not que.empty():
            distance, node = que.get()
            if distance > distances[node]:  # 없어도 작동은 하지만.. 속도를 위해..
                continue
            for a, b, cost in road:
                if a == node:
                    next_dist = cost + distance
                    if next_dist < distances[b]:
                        distances[b] = next_dist
                        que.put((next_dist, b))
                elif b == node:
                    next_dist = cost + distance
                    if next_dist < distances[a]:
                        distances[a] = next_dist
                        que.put((next_dist, a))
        return sum(1 for d in distances if d <= K)
    테스트 1 〉	통과 (0.54ms, 10.9MB)
    테스트 2 〉	통과 (0.52ms, 10.8MB)
    테스트 3 〉	통과 (0.49ms, 10.8MB)
    테스트 4 〉	통과 (0.52ms, 10.8MB)
    테스트 5 〉	통과 (0.57ms, 10.8MB)
    테스트 6 〉	통과 (0.55ms, 10.8MB)
    테스트 7 〉	통과 (0.53ms, 10.8MB)
    테스트 8 〉	통과 (0.54ms, 10.8MB)
    테스트 9 〉	통과 (0.48ms, 10.8MB)
    테스트 10 〉	통과 (0.59ms, 10.8MB)
    테스트 11 〉	통과 (0.57ms, 10.8MB)
    테스트 12 〉	통과 (0.73ms, 10.8MB)
    테스트 13 〉	통과 (0.64ms, 10.8MB)
    테스트 14 〉	통과 (2.71ms, 11.1MB)
    테스트 15 〉	통과 (4.07ms, 11.6MB)
    테스트 16 〉	통과 (0.61ms, 10.8MB)
    테스트 17 〉	통과 (0.64ms, 10.8MB)
    테스트 18 〉	통과 (1.67ms, 10.9MB)
    테스트 19 〉	통과 (4.58ms, 11.2MB)
    테스트 20 〉	통과 (1.58ms, 10.9MB)
    테스트 21 〉	통과 (5.14ms, 12.3MB)
    테스트 22 〉	통과 (2.12ms, 10.8MB)
    테스트 23 〉	통과 (5.77ms, 12MB)
    테스트 24 〉	통과 (3.94ms, 11.3MB)
    테스트 25 〉	통과 (6.73ms, 13.4MB)
    테스트 26 〉	통과 (6.75ms, 13.3MB)
    테스트 27 〉	통과 (6.81ms, 13.4MB)
    테스트 28 〉	통과 (7.47ms, 13.6MB)
    테스트 29 〉	통과 (7.01ms, 13.5MB)
    테스트 30 〉	통과 (6.55ms, 13.6MB)
    테스트 31 〉	통과 (0.83ms, 10.8MB)
    테스트 32 〉	통과 (0.96ms, 10.8MB)

    힙큐와 우선순위큐와의 속도 비교도 한번.. 

    def solution(N, road, K):
        from heapq import heappush, heappop
        distances = [float('inf') for i in range(N + 1)]
        distances[1] = 0
        que = []
        heappush(que, (0, 1))
        while que:
            distance, node = heappop(que)
            if distance > distances[node]:  # 없어도 작동은 하지만.. 속도를 위해..
                continue
            for a, b, cost in road:
                if a == node:
                    next_dist = cost + distance
                    if next_dist < distances[b]:
                        distances[b] = next_dist
                        heappush(que, (next_dist, b))
                elif b == node:
                    next_dist = cost + distance
                    if next_dist < distances[a]:
                        distances[a] = next_dist
                        heappush(que, (next_dist, a))
        return sum(1 for d in distances if d <= K)
    테스트 1 〉	통과 (0.05ms, 10.8MB)
    테스트 2 〉	통과 (0.05ms, 10.8MB)
    테스트 3 〉	통과 (0.05ms, 10.7MB)
    테스트 4 〉	통과 (0.06ms, 10.9MB)
    테스트 5 〉	통과 (0.07ms, 10.8MB)
    테스트 6 〉	통과 (0.05ms, 10.7MB)
    테스트 7 〉	통과 (0.06ms, 10.8MB)
    테스트 8 〉	통과 (0.06ms, 10.8MB)
    테스트 9 〉	통과 (0.04ms, 10.9MB)
    테스트 10 〉	통과 (0.06ms, 10.8MB)
    테스트 11 〉	통과 (0.07ms, 10.8MB)
    테스트 12 〉	통과 (0.16ms, 10.8MB)
    테스트 13 〉	통과 (0.11ms, 10.8MB)
    테스트 14 〉	통과 (1.96ms, 11.1MB)
    테스트 15 〉	통과 (2.95ms, 11.6MB)
    테스트 16 〉	통과 (0.08ms, 10.9MB)
    테스트 17 〉	통과 (0.10ms, 10.8MB)
    테스트 18 〉	통과 (0.88ms, 10.7MB)
    테스트 19 〉	통과 (3.52ms, 11.2MB)
    테스트 20 〉	통과 (0.79ms, 10.8MB)
    테스트 21 〉	통과 (4.15ms, 12.3MB)
    테스트 22 〉	통과 (1.22ms, 10.9MB)
    테스트 23 〉	통과 (4.38ms, 12MB)
    테스트 24 〉	통과 (2.91ms, 10.9MB)
    테스트 25 〉	통과 (5.63ms, 13.2MB)
    테스트 26 〉	통과 (5.96ms, 13.3MB)
    테스트 27 〉	통과 (5.41ms, 13.4MB)
    테스트 28 〉	통과 (6.24ms, 13.6MB)
    테스트 29 〉	통과 (5.91ms, 13.6MB)
    테스트 30 〉	통과 (6.18ms, 13.5MB)
    테스트 31 〉	통과 (0.20ms, 10.8MB)
    테스트 32 〉	통과 (0.34ms, 10.9MB)

    최댓값이 필요할 때 type이 있는 언어는 
    type에 따른 최댓값을 이용하는 경우가 많은데, 
    파이썬은 type이 없어서 애매하다.

    이때 math.inf 나 sys.maxsize 등을 이용해도 되겠지만, 
    외부 모듈을 불러와야 하는 불편함이 있어서
    float('inf')를 즐겨 쓴다. 

    반응형
Designed by Tistory.