반응형

programmers.co.kr/learn/courses/30/lessons/64064

 

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

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

programmers.co.kr

문제 설명

user_id 중에서 banned_id에 의해 필터링되는 user_id 목록의 경우의 수를 구하는 문제입니다.

문제의 설명이 꽤 길어서 링크를 함께 첨부하였습니다

자세한 문제 설명은 위 링크를 참조하세요!


풀이 과정

문제에서 배열의 범위가 굉장히 작기 때문에, 완전탐색을 이용하여 풀어도 됩니다!

 

그래서 저는 순열(permutation)을 이용하여 user_id로 만들 수 있는 모든 경우의 수를 banned_id와 비교하였습니다.

 

아래 코드의 solution부분부터 보게되면,

permutations(user_id, len(banned_id))를 통해 banned_id 배열의 길이만큼을 user_id에서 뽑아냅니다.

예를들어, banned_id = ["fr*d*", "abc1**"] 이면 user_id에서 두 개를 뽑아내겠죠?

 

그 다음 뽑은 user_id와 banned_id를 비교합니다. 그 부분이 check함수입니다.

 

check 함수로 이동하여,

banned_id의 원소와 candidates의 원소를 하나씩 비교하는데,

두 원소의 길이가 다르다면, 당연히 일치하지 않기 때문에 False처리를 해주고

 

일치하는 경우, 문자 하나하나 따져가며 검사합니다.

banned_id[i]의 n번째 인덱스가 별표인경우는 그 인덱스는 모든 문자가 가능하므로 continue해주고,

두 원소의 똑같은 인덱스의 문자가 일치하지 않는 경우, False 처리를 해줍니다.

 

모든 for문을 통과하면 True를 리턴합니다.

 

다시 solution의 check로 돌아와보면, if문을 True로 통과했기 때문에

candidates라는 변수를 set형식으로 바꿔줍니다. ( 중복 방지를 위해 )

 

그리고 이 candidates가 answer에 없으면, answer에 추가해주면 됩니다.

from itertools import permutations

def check(candidates, banned_id):
    for i in range(len(banned_id)):
        if len(candidates[i]) != len(banned_id[i]):
            return False
        for a, b in zip(candidates[i], banned_id[i]):
            if b == "*":
                continue
            if a != b:
                return False
    return True


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

    for candidates in permutations(user_id, len(banned_id)):
        if check(candidates, banned_id):
            candidates = set(candidates)
            if candidates not in answer:
                answer.append(candidates)

    return len(answer)

 

https://github.com/HongEunho

 

HongEunho - Overview

📖 Android, Java, Kotlin, Algorithm. HongEunho has 15 repositories available. Follow their code on GitHub.

github.com

전체 문제 & 코드는 위의 깃에 정리되어 있습니다.

팔로우 & 맞팔은 환영입니다 !

반응형

+ Recent posts