from collections import defaultdict
from collections import Counter
from itertools import combinations
def solution(relation):
result = []
row = len(relation)
col = len(relation[0])
arr = list(range(col))
d = defaultdict(list)
# 유일성
for i in range(col):
for j in range(row):
d[i].append(relation[j][i])
for idx in range(1, col + 1):
temp = list((combinations(arr, idx)))
for tup in temp:
build = [''] * row
for i in tup:
for j in range(row):
build[j] += d[i][j]
a = Counter(build).most_common(1)
if a[0][1] == 1:
result.append(tup)
# 최소성
answer = set(result[:])
for i in range(len(result)):
for j in range(i + 1, len(result)):
if set(result[i]).issubset(set(result[j])):
answer.discard(result[j])
return len(answer)
유일성을 만족시키는 모든 경우의 수를 구한다음, 최소성이 되는것만을 골라내는 방식으로 접근했다. 컬럼과 로우의 범위가 매우 작았기 때문에 combinations
라이브러리를 사용해 모든 경우를 구하는게 가능하다고 생각했고, 유일성과 최소성을 만족시키는 조합을 동시에 찾는 방법은 너무 복잡하다고 생각했다.
set()
을 다시한번 공부했다. 이 문제는 issubset()
을 사용하면 정말 편하게 풀 수 있다.
a = {4, 2, 3}
b = {1, 2, 3, 4, 5}
c = {9}
d = {3}
# a가 b의 부분집합이면 True, 아니면 False 반환
# a, b 순서 상관있음
print(a.issubset(b)) # True
print(b.issubset(a)) # False
# disjoint = 서로소 집합
# 교집합이 하나라도 있으면 False, 없으면 True
# a, b 순서는 상관없음
print(b.isdisjoint(a)) # False
print(d.isdisjoint(b)) # False
print(c.isdisjoint(b)) # True
print(a.intersection(b)) # {2, 3, 4}
print(a & b) # {2, 3, 4}
discard(원소), 원소가 없어도 에러가 발생하지 않는다.
b.discard(5)
b.discard(5)
# b.remove(5) 에러 발생
print(b)
s = set()
s.add((1,2))
print(s) # {(1, 2)}
# s.add([1,2]) # 에러, set의 원소에는 값이 바뀔 수 있는 list는 들어갈 수 없다.