본문 바로가기
프로그래머스/Python

[프로그래머스] 거리두기 확인하기 - 파이썬(Python) - 우당탕탕 개발자 되기 프로젝트

by 우당탕탕 개발자 2024. 6. 26.
728x90
반응형

 

 

프로그래머스

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

programmers.co.kr

 

1. 문제 설명

반응형

2. 풀이과정

해당 문제는 각 대기실에 있는 모든 응시자가 거리두기를 지키고 있는지 확인하는 문제이다.

응시자 간 거리가 맨해튼 거리로 2 이하이면 안되고, 만약 거리가 맨해튼 거리로 2 이하일 경우 그 사이가 파티션으로 막혀있으면 거리두기를 지키는 것이다.

모든 응시자가 거리두기를 지키고 있는지 확인하려면 응시자 간 모든 거리를 판별해야 한다.

만약 두 응시자 간 거리가 2 이하라면, 두 응시자는 가로로 나란히, 세로로 나란히, 대각선으로 나란히, 총 3가지 경우 중 하나로 위치해 있을 것이다.

이 3가지 경우를 모두 판별하여 모두 거리두기를 만족해야 거리두기를 지키고 있는 것이다.

만약 두 응시자가 가로로 나란히 있거나 세로로 나란히 있는 경우라면, 두 응시자 사이에 파티션이 존재해야 한다.

만약 두 응시자가 대각선으로 나란히 있는 경우라면, 각 위아래와 좌우 사이에 파티션이 존재해야 한다.

이 같은 조건이 모든 응시자가 만족해야 해당 대기실에서 거리두기가 지켜지고 있다고 판단할 수 있다.

 

  1. 응시자 간의 조합을 구하기 위해 combinations 함수를 사용한다. from itertools import combinations
  2. 응시자 간의 조합에서 거리두기가 지켜지고 있는지 판별하는 함수를 생성한다. def check(case)
    1. 응시자 간 조합을 하나씩 불러오며 for c in case
      1. 각 응시자의 위치 좌표를 저장한다. x1, y1 = c[0]
      2. x2, y2 = c[1]
      3. 두 응시자 간의 맨해튼 거리를 구한다. d = abs(x1 - x2) + abs(y1 - y2)
      4. 만약 두 응시자 간의 맨해튼 거리가 2 이하이면 if (d <= 2)
        1. 두 응시자가 가로로 나란히 있을 경우 if (x1 == x2)
          1. 두 응시자 사이에 파티션이 존재하지 않으면 거리두기가 지켜지지 않은 것이므로 False를 반환한다. if (map[x1][max(y1, y2) - 1] != 'X'): return False
        2. 두 응시자가 세로로 나란히 있을 경우 elif (y1 == y2)
          1. 두 응시자 사이에 파티션이 존재하지 않으면 거리두기가 지켜지지 않은 것이므로 False를 반환한다. if (map[max(x1, x2) - 1][y1] != 'X'): return False
        3. 두 응시자가 대각선으로 나란히 있을 경우 else
          1. 두 응시자 사이에 파티션이 존재하지 않으면 거리두기가 지켜지지 않은 것이므로 False를 반환한다. if (map[x1][y2] != 'X') or (map[x2][y1] != 'X'): return False
    2. 만약 모든 응시자가 거리두기를 지키고 있다면 True를 반환한다. return True
  3. 입력으로 받은 모든 대기실을 하나씩 불러온다. for case in places
    1. 각 대기실을 따로 저장할 리스트를 생성한다. map = []
    2. 각 대기실의 행을 한 줄씩 불러오며 각 행의 문자열을 개별 문자로 나누어 리스트로 생성하고 이를 대기실 리스트에 추가한다. for line in case: map.append(list(i for i in line))
    3. 응시자의 위치를 저장할 리스트를 생성한다. spot = []
    4. 각 행과 열의 위치를 하나씩 불러오며 for row in range(5): for col in range(5)
      1. 만약 대기실에서 해당 위치에 응시자가 있으면 해당 위치를 리스트 형태로 응시자 위치 리스트에 추가한다. if (map[row][col] == 'P'): spot.append([row, col])
    5. 응시자 위치 리스트에서 2개씩을 뽑아 만들 수 있는 조합의 경우를 리스트로 저장한다.  case = list(combinations(spot, 2))
    6. 만약 해당 조합의 거리두기를 확인했을 때 거리두기가 지켜지고 있어 True가 반환된다면 정답 리스트에 1을 추가하고 if check(case): answer.append(1)
    7. 반면에 거리두기가 지켜지지 않아 False가 반환된다면 정답 리스트에 0을 추가한다. else: answer.append(0)

3. 소스코드

from itertools import combinations

def solution(places):
    answer = []
    
    def check(case):
        for c in case:
            x1, y1 = c[0]
            x2, y2 = c[1]
            d = abs(x1 - x2) + abs(y1 - y2)
            if (d <= 2):
                if (x1 == x2):
                    if (map[x1][max(y1, y2) - 1] != 'X'):
                        return False
                elif (y1 == y2):
                    if (map[max(x1, x2) - 1][y1] != 'X'):
                        return False
                else:
                    if (map[x1][y2] != 'X') or (map[x2][y1] != 'X'):
                        return False
                    
        return True

    for case in places:
        map = []
        for line in case:
            map.append(list(i for i in line))

        spot = []
        for row in range(5):
            for col in range(5):
                if (map[row][col] == 'P'):
                    spot.append([row, col])
                    
        case = list(combinations(spot, 2))
        if check(case):
            answer.append(1)
        else:
            answer.append(0)

    return answer
728x90
반응형