두 개의 리스트가 주어졌을 때, 한쪽 리스트를 순환 회전시키면 다른 리스트와 완전히 같아지는지 확인하는 것이 이번 글의 목표입니다. 시작 위치만 다를 뿐 요소의 나열 순서가 동일한 두 리스트를 순환적으로 동일(circularly identical)하다고 표현합니다.
예시
입력 : A = [100, 100, 10, 10, 100]
B = [100, 100, 100, 10, 10]
출력 : True
설명
리스트 A의 요소들을 순환적으로 회전하면 리스트 B와 동일한 배열을 만들 수 있습니다. 두 리스트는 구성 요소와 순서 패턴이 같고 시작 지점만 다르기 때문에 결과는 True입니다.
알고리즘
- 비교할 첫 번째 리스트와 두 번째 리스트를 생성합니다.
- 리스트를 map 객체로 변환합니다.
- join() 메서드를 사용해 리스트 객체를 하나의 문자열로 연결합니다.
- 리스트 A를 두 번 반복(A * 2)한 뒤 다시 map으로 변환합니다. 리스트를 두 배로 늘리면 가능한 모든 순환 회전 결과가 그 안에 포함됩니다.
- 두 문자열을 비교합니다. 결과가 True이면 두 리스트는 순환적으로 동일하고, False이면 동일하지 않습니다.
예제 코드
# 두 리스트가 순환적으로 동일한지 확인하는 Python 프로그램
A=list()
n=int(input("Enter the size of the First List ::"))
print("Enter the Element of First List ::")
for i in range(int(n)):
k=int(input(""))
A.append(k)
B=list()
n1=int(input("Enter the size of the Second List ::"))
print("Enter the Element of the Second List ::")
for i in range(int(n1)):
k=int(input(""))
B.append(k)
C=list()
n3=int(input("Enter the size of the Third List ::"))
print("Enter the Element of the Third List ::")
for i in range(int(n3)):
k=int(input(""))
C.append(k)
print("Compare First List and Second List ::>")
print(' '.join(map(str, B)) in ' '.join(map(str, A * 2)))
print("Compare Second List and Third List ::>")
print(' '.join(map(str, C)) in ' '.join(map(str, A * 2)))
핵심은 ' '.join(map(str, A * 2)) 부분입니다. 원본 리스트를 두 번 이어 붙인 문자열 안에는 가능한 모든 순환 회전 결과가 부분 문자열로 존재하므로, 비교 대상 리스트의 문자열이 포함되어 있는지만 확인하면 됩니다.
실행 결과
Enter the size of the First List :: 5 Enter the Element of First List :: 10 10 0 0 10 Enter the size of the Second List :: 5 Enter the Element of the Second List :: 10 10 10 0 0 Enter the size of the Third List :: 5 Enter the Element of the Third List :: 1 10 10 0 0 Compare First List and Second List ::> True Compare Second List and Third List ::> False
첫 번째 리스트와 두 번째 리스트는 순환 회전 시 서로 일치하므로 True가 출력됩니다. 반면 세 번째 리스트는 요소 구성 자체가 달라 순환적으로 동일하지 않으므로 False가 출력됩니다.
참고: deque를 활용한 더 명확한 방법
문자열 변환 방식은 코드가 간결하지만, 두 리스트의 길이가 같은지 미리 확인하지 않으면 잘못된 결과가 나올 수 있습니다. 요소를 하나씩 직접 비교하는 방식이 더 안전하며, collections.deque의 rotate()를 사용하면 순환 회전을 손쉽게 구현할 수 있습니다.
from collections import deque
def is_circular_identical(a, b):
if len(a) != len(b):
return False
da, db = deque(a), deque(b)
for _ in range(len(a)):
if list(da) == list(db):
return True
da.rotate(1) # 한 칸씩 회전하며 모든 경우를 확인
return False
print(is_circular_identical([100, 100, 10, 10, 100], [100, 100, 100, 10, 10])) # True
print(is_circular_identical([1, 12], [11, 2])) # False