https://programmers.co.kr/learn/courses/30/lessons/64064?language=python3

 

코딩테스트 연습 - 불량 사용자

개발팀 내에서 이벤트 개발을 담당하고 있는 무지는 최근 진행된 카카오이모티콘 이벤트에 비정상적인 방법으로 당첨을 시도한 응모자들을 발견하였습니다. 이런 응모자들을 따로 모아 불량 ��

programmers.co.kr



Solution

import itertools

def ban_check(cb, banned_id):
    for i in range(len(cb)):
        if len(cb[i]) != len(banned_id[i]):
            return False
        for j in range(len(cb[i])):
            if banned_id[i][j] != '*' and cb[i][j] != banned_id[i][j]:
                return False
    return True

def solution(user_id, banned_id):
    cnt = 0
    result = []
    answer = []
    cb_user_id = list(itertools.permutations(user_id, len(banned_id)))
    for cb in cb_user_id:
        if ban_check(cb, banned_id):
            cb = list(cb)
            cb = sorted(cb)
            result.append(cb)
    for i in result:
        if not i in answer:
            answer.append(i)
    return len(answer)

 

처음에는 banned_id 하나씩 user_id랑 비교한 후 user_id에서 매핑되는 id들을 구하는 방법으로 풀려고 했으나, 풀다보니 어려워져서 이 방법으로 풀었다🤯

user_id의 크기도 8 이하 이므로 나올 수 있는 모든 경우의 수를 구하고, 경우의 수 하나씩 검사한다. 문제에서 제재 아이디 목록의 순서가 없다고 했으므로, 모든 경우의 수를 처음에는 itertoolscombinations를 써서 구했는데 테스트 케이스 3에서 예외가 생겼다. 이유는 내 풀이대로 하면 한 경우의 수의 id와 banned_id의 id를 인덱스로 앞에서부터 비교를 하기 때문이였다. 이렇게 비교를 하다보니 순서가 엉켜버린 것이다. 즉 순서가 없는 경우를 구하는 것이지만 순서가 있는 경우의 수를 통해 결과 도출을 해야한다. 그래서 permutations로 모든 경우의 수cb_user_id를 구했다. 하나씩 비교를 한 후 아닌 경우는 무시하고, 맞다면 튜플cb를 리스트로 바꾸고 정렬해서 result 배열에 넣어준다. 이때 result 배열의 길이는 정답의 2배수가 나올 것이다. 정렬을 해서 넣었기 때문에 겹치는 것을 필터링한 후 나온 길이를 리턴한다.

 

 


생강강

,