문제를 그대로 구현하다보니 어렵게 풀고 하드코딩으로 푼거 같다.
최소성을 체크하는데 issubset을 이용하면 편리한것 같다.
ex) x.issubset(y) # x가 y의 서브 set 맞나? 체크한다.
내 코드를 리뷰하면서도 내가 헷갈려서 결과를 상세히 기록해놨다...
다른사람 코드
combi = []
for i in range(1, col+1):
combi.extend(combinations(range(col), i))
for i in combi:
tmp = [tuple([item[key] for key in i]) for item in relation]
(('100',), ('200',), ('300',), ('400',), ('500',), ('600',)) 이 부분을 만드는 코드가 간결한것 같다. 다른 사람코드는 이걸 하나씩 만든 후 최소성, 유일성을 비교한다.
나는 dict로 한꺼번에 넣고 최소성, 유일성 비교를 한다. 그래서 더 복잡하게 푼것 같다..
from itertools import *
from collections import *
def solution(relation):
answer = 0
n = len(relation[0])
colums = []
for i in range(n):
colums.append(i)
cols = []
comb = defaultdict(list)
for i in range(1,n+1):
for j,r in enumerate(relation):
# relation의 요소별로 1~n개 조합을 구한다. cols 결과
# [ [('100',), ('ryan',), ('music',), ('2',)],
# [('200',), ('apeach',), ('math',), ('2',)],
# [('300',), ('tube',), ('computer',), ('3',)],
# [('400',), ('con',), ('computer',), ('4',)],
# [('500',), ('muzi',), ('music',), ('3',)],
# [('600',), ('apeach',), ('music',), ('2',)] ]
cols.append(list(combinations(r,i)))
# cols를 인덱스별로 zip으로 묶는다.
# [ (('100',), ('200',), ('300',), ('400',), ('500',), ('600',)),
# (('ryan',), ('apeach',), ('tube',), ('con',), ('muzi',), ('apeach',)),
# (('music',), ('math',), ('computer',), ('computer',), ('music',), ('music',)),
# (('2',), ('2',), ('3',), ('4',), ('3',), ('2',)) ]
candidate = list(zip(*cols))
# 컬럼별로 1~n개 조합을 구한다.
# combiantion [(0,), (1,), (2,), (3,)]
for j,key in enumerate(list(combinations(colums, i))):
comb[key] = candidate[j]
cols.clear()
# 모든 조합을 계산한 comb결과
# {(0,): (('100',), ('200',), ('300',), ('400',), ('500',), ('600',)),
# (1,): (('ryan',), ('apeach',), ('tube',), ('con',), ('muzi',), ('apeach',)),
# (2,): (('music',), ('math',), ('computer',), ('computer',), ('music',), ('music',)),
# (3,): (('2',), ('2',), ('3',), ('4',), ('3',), ('2',)),
# (0, 1): (('100', 'ryan'), ('200', 'apeach'), ('300', 'tube'), ('400', 'con'), ('500', 'muzi'), ('600', 'apeach')),
# (0, 2): (('100', 'music'), ('200', 'math'), ('300', 'computer'), ('400', 'computer'), ('500', 'music'), ('600', 'music')),
# (0, 3): (('100', '2'), ('200', '2'), ('300', '3'), ('400', '4'), ('500', '3'), ('600', '2')),
# (1, 2): (('ryan', 'music'), ('apeach', 'math'), ('tube', 'computer'), ('con', 'computer'), ('muzi', 'music'), ('apeach', 'music')),
# ...............
# (1, 2, 3): (('ryan', 'music', '2'), ('apeach', 'math', '2'), ('tube', 'computer', '3'), ('con', 'computer', '4'), ('muzi', 'music', '3'), ('apeach', 'music', '2')),
# (0, 1, 2, 3): (('100', 'ryan', 'music', '2'), ('200', 'apeach', 'math', '2'), ('300', 'tube', 'computer', '3'), ('400', 'con', 'computer', '4'), ('500', 'muzi', 'music', '3'), ('600', 'apeach', 'music', '2'))})
result = []
for i in comb:
# 유일성 체크
if len(comb[i]) == len(set(comb[i])):
check = True
if len(result)==0:
result.append(set(i))
# 최소성 체크
for j in result:
if j.issubset(set(i)):
check =False
if check:
result.append(set(i))
return len(result)