[프로그래머스] 후보키 (Python 파이썬)

dh·2022년 12월 27일
0
post-thumbnail

문제를 그대로 구현하다보니 어렵게 풀고 하드코딩으로 푼거 같다.
최소성을 체크하는데 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)

0개의 댓글