겹치는 선분의 길이 ( set , &, | )
[문제 설명]
선분 3개가 평행하게 놓여 있습니다.
세 선분의 시작과 끝 좌표가 [[start, end], [start, end], [start, end]] 형태로 들어있는
2차원 배열 lines가 매개변수로 주어질 때, 두 개 이상의 선분이 겹치는 부분의 길이를
return 하도록 solution 함수를 완성해보세요.
lines가 [[0, 2], [-3, -1], [-2, 1]]일 때 그림으로 나타내면 다음과 같습니다.
선분이 두 개 이상 겹친 곳은 [-2, -1], [0, 1]로 길이 2만큼 겹쳐있습니다.
[제한사항]
- lines의 길이 = 3
- lines의 원소의 길이 = 2
- 모든 선분은 길이가 1 이상입니다.
- lines의 원소는 [a, b] 형태이며, a, b는 각각 선분의 양 끝점 입니다.
-100 ≤ a < b ≤ 100
[입출력 예]
lines | result |
[[0, 1], [2, 5], [3, 9]] | 2 |
[[-1, 1], [1, 3], [3, 9]] | 0 |
[[0, 5], [3, 9], [1, 10]] | 8 |
[입출력 예 설명]
입출력 예 #1)
두 번째, 세 번째 선분 [2, 5], [3, 9]가 [3, 5] 구간에 겹쳐있으므로 2를 return 합니다.
입출력 예 #2)
겹친 선분이 없으므로 0을 return 합니다.
입출력 예 #3)
첫 번째와 두 번째 선분이 [3, 5] 구간에서 겹칩니다.
첫 번째와 세 번째 선분 [1, 5] 구간에서 겹칩니다.
두 번째와 세 번째 선분 [3, 9] 구간에서 겹칩니다.
따라서 [1, 9] 구간에 두 개 이상의 선분이 겹쳐있으므로, 8을 return 합니다.
[나의 풀이]
def solution(lines):
# 1. range를 정수 list로 바꾸기
list = []
for line in lines:
range_line = range(line[0], line[1])
int_list = [int(i) for i in range_line]
list.append(int_list)
# 2. list를 set으로 바꾸기
a = set(list[0])
b = set(list[1])
c = set(list[2])
# 3. 교집합 찾아 개수 구하기
return len((a & b) | (b & c) | (c & a))
[설명]
- 겹치는 길이를 구하는 대신에 겹치는 정수가 몇 개인지 구한다.
1. range를 정수 list로 바꾸기
lines = [[0, 5], [3, 9], [1, 10]]
list = []
for line in lines:
range_line = range(line[0], line[1])
int_list = [int(i) for i in range_line]
print(int_list)
list.append(int_list)
print(list)
Out[1]:
[0, 1, 2, 3, 4] # list[0]
[3, 4, 5, 6, 7, 8] # list[1]
[1, 2, 3, 4, 5, 6, 7, 8, 9] # list[2]
[[0, 1, 2, 3, 4], [3, 4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7, 8, 9]] # list
> range(0,5) 안에 있는 수를 정수로 나타내면 아래와 같이 나타낼 수 있다.
[0, 1, 2, 3, 4]
2. list를 set으로 바꾸기
a = set(list[0])
b = set(list[1])
c = set(list[2])
print(a)
print(b)
print(c)
Out[2]:
{0, -1} # set( list[0] )
{1, 2} # set( list[1] )
{3, 4, 5, 6, 7, 8} # set( list[2] )
3. 교집합을 찾아 개수 구하기
print(len((a & b) | (b & c) | (c & a)))
Out[3]:
8
> 추가 설명
print('a & b = ', a&b)
print('b & c = ', b&c)
print('a & c = ', a&c)
print('(a & c) | (b & c) | (a & c) = ' , (a&c) | (b&c) | (a&c))
print('len((a & b) | (b & c) | (c & a)) = ', len((a & b) | (b & c) | (c & a)))
Out[4]:
a & b = {3, 4}
b & c = {3, 4, 5, 6, 7, 8}
a & c = {1, 2, 3, 4}
(a & c) | (b & c) | (a & c) = {1, 2, 3, 4, 5, 6, 7, 8}
len((a & b) | (b & c) | (c & a)) = 8
[다른 사람 풀이]
def solution(lines):
# 1. range를 set으로 바꾸기
sets = [set(range(min(l), max(l))) for l in lines]
# 2. 교집합의 개수 구하기
return len(sets[0] & sets[1] | sets[0] & sets[2] | sets[1] & sets[2])
[설명]
1. range를 set으로 바꾸기
lines = [[0, 5], [3, 9], [1, 10]]
sets = [set(range(min(l), max(l))) for l in lines]
print(sets)
Out[5]:
[{0, 1, 2, 3, 4}, {3, 4, 5, 6, 7, 8}, {1, 2, 3, 4, 5, 6, 7, 8, 9}]
> [나의 풀이]의 1. range를 정수 list로 바꾸기, 2. list를 set으로 바꾸기 과정을 한 줄로 정리하였다.
> [나의 풀이]에서는 range를 list로 바꾸고 난 후 set으로 바꾸었는데
[다른 사람 풀이]에서는 range를 바로 set으로 바꾸어 list에 저장하였다.
2. 교집합의 개수 구하기
len(sets[0] & sets[1] | sets[0] & sets[2] | sets[1] & sets[2])
Out[6]:
8
> [나의 풀이]의 3. 교집합을 찾아 개수 구하기 설명 참고하면 쉽게 이해할 수 있을 것이다.
[다른 사람 풀이 수정]
def solution(lines):
# 1. range를 set으로 바꾸기
[a, b, c] = [set(range(min(l), max(l))) for l in lines]
# 2. 교집합의 개수 구하기
return len(a & b | a & c | b & c)
> [다른 사람 풀이]를 조금 더 간단하게 수정하였다.