주니어 데이터 엔지니어 우솨's 개발일지

코딩 테스트(python) [PCCP 기출문제] 3번 / 충돌위험 찾기 본문

코딩 테스트

코딩 테스트(python) [PCCP 기출문제] 3번 / 충돌위험 찾기

우솨 2024. 12. 17. 01:29

 

문제 설명

어떤 물류 센터는 로봇을 이용한 자동 운송 시스템을 운영합니다. 운송 시스템이 작동하는 규칙은 다음과 같습니다.

  1. 물류 센터에는 (r, c)와 같이 2차원 좌표로 나타낼 수 있는 n개의 포인트가 존재합니다. 각 포인트는 1~n까지의 서로 다른 번호를 가집니다.
  2. 로봇마다 정해진 운송 경로가 존재합니다. 운송 경로는 m개의 포인트로 구성되고 로봇은 첫 포인트에서 시작해 할당된 포인트를 순서대로 방문합니다.
  3. 운송 시스템에 사용되는 로봇은 x대이고, 모든 로봇은 0초에 동시에 출발합니다. 로봇은 1초마다 r 좌표와 c 좌표 중 하나가 1만큼 감소하거나 증가한 좌표로 이동할 수 있습니다.
  4. 다음 포인트로 이동할 때는 항상 최단 경로로 이동하며 최단 경로가 여러 가지일 경우, r 좌표가 변하는 이동을 c 좌표가 변하는 이동보다 먼저 합니다.
  5. 마지막 포인트에 도착한 로봇은 운송을 마치고 물류 센터를 벗어납니다. 로봇이 물류 센터를 벗어나는 경로는 고려하지 않습니다.

이동 중 같은 좌표에 로봇이 2대 이상 모인다면 충돌할 가능성이 있는 위험 상황으로 판단합니다. 관리자인 당신은 현재 설정대로 로봇이 움직일 때 위험한 상황이 총 몇 번 일어나는지 알고 싶습니다. 만약 어떤 시간에 여러 좌표에서 위험 상황이 발생한다면 그 횟수를 모두 더합니다.

운송 포인트 n개의 좌표를 담은 2차원 정수 배열 points와 로봇 x대의 운송 경로를 담은 2차원 정수 배열 routes가 매개변수로 주어집니다. 이때 모든 로봇이 운송을 마칠 때까지 발생하는 위험한 상황의 횟수를 return 하도록 solution 함수를 완성해 주세요.

 

from collections import Counter

answer = 0

# 최대 x좌표와 최대 y좌표를 찾음
max_0 = max([i[0] for i in points])  # 모든 점에서 x좌표의 최대값
max_1 = max([i[1] for i in points])  # 모든 점에서 y좌표의 최대값

n = len(points)  # 점의 개수
m = len(routes)  # 경로의 개수
p_array = []  # 각 경로에 포함된 점들의 좌표를 저장할 배열

# 각 경로(routes[i])에 속한 점들의 좌표를 가져와 p_array에 저장
for i in range(m):
    p = []
    for j in routes[i]:
        p.append(points[j - 1])  # 인덱스 보정(j-1) 후 points에서 좌표 가져오기
    p_array.append(p)

l = len(p_array) - 1  # 경로 배열의 마지막 인덱스
t = 0
array = []  # 각 경로의 세부 점을 저장할 배열

# 모든 경로를 처리
while t <= l:
    temp = []  # 현재 경로의 점들을 담을 임시 배열
    a = p_array[t]  # 현재 경로의 점들의 좌표 리스트
    b = a[0].copy()  # 경로의 시작점 좌표 복사
    temp.append(b.copy())  # 시작점을 temp에 추가

    # 현재 경로의 두 점 사이를 연결하며 모든 점을 추가
    for k in range(1, len(a)):
        while b[0] != a[k][0] or b[1] != a[k][1]:  # 현재 점이 목표 점에 도달할 때까지
            if b[0] < a[k][0]:  # x좌표를 목표점 쪽으로 이동
                b[0] += 1
            elif b[0] > a[k][0]:
                b[0] -= 1
            elif b[1] < a[k][1]:  # y좌표를 목표점 쪽으로 이동
                b[1] += 1
            elif b[1] > a[k][1]:
                b[1] -= 1
            temp.append(b.copy())  # 이동한 점을 temp에 추가
    array.append(temp.copy())  # 현재 경로의 점들을 array에 추가
    t += 1

# 모든 경로 중 가장 긴 세부 점 배열의 길이 찾기
max_length = max(len(sub_array) for sub_array in array)

# 각 시간 단계별로 모든 경로에서 동일한 점의 중복을 확인
for i in range(max_length):
    values_at_i = []  # 현재 시간 단계에서 각 경로에 존재하는 점들의 리스트
    for sub_array in array:
        if i < len(sub_array):  # 현재 경로가 아직 끝나지 않았으면
            values_at_i.append(tuple(sub_array[i]))  # 해당 점을 추가
    count = Counter(values_at_i)  # 현재 시간 단계에서 중복 점 개수를 카운트
    for value, cnt in count.items():
        if cnt > 1:  # 중복된 점이 있다면
            answer += 1  # 중복된 점의 개수를 결과에 추가