문제: https://programmers.co.kr/learn/courses/30/lessons/64064#

풀이

여러번 풀어보려 시도했으나 풀지 못했던 문제.
다음과 같은 과정으로 해결했다.

  1. 불량 사용자가 될 수 있는 후보를 골라낸다. (정규식 사용)
  2. 1에서 구한 것을 바탕으로 모든 가능한 경우의 수를 구한다. (product 사용)
  3. 2에서 구한 경우에서 중복을 제거한다. 3-1. len(candidate_tuple) == len(set(candidate_tuple))으로 튜플 내에 겹치는 원소가 있는지 판단 3-2. 튜플을 리스트로 바꾸고 정렬, 다시 튜플로 변환한 뒤 set에 넣어 튜플끼리 중복을 없앤다.
  4. 해당 set의 length를 구하면 정답.

소스코드

import re
from itertools import product

def solution(user_id, banned_id):
    candidates_id = []

    for ban in banned_id:
        candidates = []
        ban_re = re.compile(ban.replace("*", "\w"))

        for user in user_id:
            if len(user) == len(ban) and ban_re.match(user) is not None:
                candidates.append(user)

        candidates_id.append(candidates)

    candidates_product = list(product(*candidates_id))
    new_candidates = []

    for candidate_tuple in candidates_product:
        if len(candidate_tuple) == len(set(candidate_tuple)):
            new_candidates.append(candidate_tuple)

    answer_set = set()
    for candidate in new_candidates:
        candidate_list = sorted(list(candidate))
        answer.add(tuple(candidate_list))
        
    return len(answer_set)