새소식

반응형
코딩 테스트

[2019 KAKAO BLIND RECRUITMENT] 후보키

  • -
728x90
반응형

문제

  • 학생들의 인적사항이 주어졌을 때 후보 키의 최대 개수 구하기
  • 1 <= 인적사항 개수 <= 8
  • 1 <= relation 개수 <= 20

 

풀이 (1h 30mins...)

  • 최소성 -> 이미 후보키가 될 수 있는 조합에는 추가 컬럼을 더하면 안된다.
  • 유일성 -> 해당 후보키를 조합한 데이터는 단 하나만 존재해야 한다.

 

  • ✅ 최소성 판단에서 막힘
  • 처음에는 후보키를 생성하는 방식으로 접근했는데 계속 중복되는 경우가 발생함
    • [0, 1, 2, 3] 키 중 후보키를 찾기 -> [ 1, 2, 3] 중에서 길이가 2인 후보키 찾기 -> [(1, 3), (2, 3)] 중 길이가 3인 후보키 찾기
  •  결국 중복을 완벽하게 제어하는 방법을 못찾아서 전체 컬럼 조합에서 최소성을 만족하지 못하는 키를 제거함

 

from collections import deque
from itertools import combinations

# 유일성 확인 (해당 키 조합의 데이터가 단 하나 존재하는지 확인)
def unique(cand, relation) :
    tmp = dict()
    for r in relation :
        key = " ".join([r[i] for i in cand])
        if key in tmp :
            return False
        else :
            tmp[key] = 1
    return True

# 최소성 확인 (해당 키 조합의 subset이 이미 후보키에 있는지 확인)
def minimality(cand, keys) :
    for k in keys :
        if set(k).issubset(set(cand)) :
            return False
    return True

def solution(relation):
    col = len(relation[0])  # 열 개수
    
    # 전체 컬럼 조합
    cands = []
    for i in range(1, col) :
        cands.extend(combinations(range(col), i))
    
    keys = set()            # 후보키 리스트
    for cand in cands :
        # 최소성과 유일성을 만족한다면 후보키에 추가한다.
        if minimality(cand, keys) and unique(cand, relation) :
            keys.add(tuple(cand))
    answer = len(keys)
    return answer if answer else 1

 

 

풀이2

  • 전체 키조합을 구한 뒤, 최소성과 유일성을 만족하는지 확인한다.

 

2023.09.04 2차 풀이
from itertools import combinations

# 최소성 확인하기
def check_minimality(num, cols, candidates) :
    for cnt in range(1, num) :
        for c in combinations(cols, cnt) :
            if c in candidates :
                return False
    return True
    
def solution(relation):
    data_n = len(relation)      # 데이터 개수
    col_n = len(relation[0])    # 컬럼 개수
    candidates = set()          # 후보키 리스트
    
    # 전체 키조합 구하기
    for cnt in range(1, col_n+1) :
        for candidate in combinations([i for i in range(col_n)], cnt) :

            # 최소성 확인
            if not check_minimality(cnt, candidate, candidates) :
                continue
      
            # 유일성 확인
            data = set()
            for i in range(data_n) :
                data.add(tuple([relation[i][col] for col in candidate]))

            if len(data) == data_n :
                candidates.add(candidate)

    return len(candidates)
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.