[프로그래머스 - 카카오] 불량 사용자

koyo·2020년 9월 29일
0

프로그래머스

목록 보기
3/3
post-thumbnail

문제

user_id 리스트와 user_id가 일부 마스킹된 banned_id 리스트가 주어진다. banned_id에 매칭되는 경우의 수는 몇개가 존재하는가?

[제한사항]

  • user_id 배열의 크기는 1 이상 8 이하입니다.
  • user_id 배열 각 원소들의 값은 길이가 1 이상 8 이하인 문자열입니다.
    • 응모한 사용자 아이디들은 서로 중복되지 않습니다.
    • 응모한 사용자 아이디는 알파벳 소문자와 숫자로만으로 구성되어 있습니다.
  • banned_id 배열의 크기는 1 이상 user_id 배열의 크기 이하입니다.
  • banned_id 배열 각 원소들의 값은 길이가 1 이상 8 이하인 문자열입니다.
    • 불량 사용자 아이디는 알파벳 소문자와 숫자, 가리기 위한 문자 '*' 로만 이루어져 있습니다.
    • 불량 사용자 아이디는 '*' 문자를 하나 이상 포함하고 있습니다.
    • 불량 사용자 아이디 하나는 응모자 아이디 중 하나에 해당하고 같은 응모자 아이디가 중복해서 제재 아이디 목록에 들어가는 경우는 없습니다.
  • 제재 아이디 목록들을 구했을 때 아이디들이 나열된 순서와 관계없이 아이디 목록의 내용이 동일하다면 같은 것으로 처리하여 하나로 세면 됩니다.

문제풀이

순열을 활용하여 user_id를 banned_id의 수에 맞게 뽑은 뒤 확인한다.
순열의 경우 순서가 바뀌었지만 같은 경우가 존재할 수 있으므로 set의 형태로 넣어준다.

from itertools import permutations

def isMatch(user_set, banned_set):
    # 선택된 user_set 집합이 banned_set의 목록들에 순서까지 맞아떨어지는가?
    for i in range(len(user_set)):
        # 길이가 맞지 않다면 False
        if len(user_set[i]) != len(banned_set[i]):
            return False
        # 마스킹 이외에 모든 부분은 같은가?
        for j in range(len(user_set[i])):
            if banned_set[i][j] == '*':
                continue
            if user_set[i][j] != banned_set[i][j]:
                return False
    return True

def solution(user_id, banned_id):
    ans = []
    for com_set in permutations(user_id, len(banned_id)):
        # user_id 중 banned_id의 수에 해당하는 만큼 고르자. 단, banned_id와의 순서를 고려해서 순열을 활용한다.
        if isMatch(com_set, banned_id):
            # 들어갈 때는 순서에 상관없이 같은 경우로 봐야하기 때문에 set으로 변경
            com_set = set(com_set) # 중복 제거
            if com_set not in ans:
                ans.append(com_set)
    return len(ans)

개선할 점

나는 왜 마스킹에 들어갈 수 있는 모든 경우의 수랑 대조하겠다는 생각을 했을까?
당시에 이 문제를 만나서 못풀었던 경험이 있는데 풀고나니 시원한 느낌이 든다.

profile
클라우드 개발자가 될 코요입니다.

0개의 댓글