[문제 링크]
https://programmers.co.kr/learn/courses/30/lessons/64064
[입출력 예]
user_id |
banned_id |
result |
["frodo", "fradi", "crodo", "abc123", "frodoc"] |
["frd", "abc1**"] |
2 |
["frodo", "fradi", "crodo", "abc123", "frodoc"] |
["rodo", "rodo", "**"] |
2 |
["frodo", "fradi", "crodo", "abc123", "frodoc"] |
["frd", "rodo", "*****", "**"] |
3 |
[최초 접근 방식]
# 경우의 수 구하듯이 접근했음.
# 이런 식으로 풀면 banned_id가 중복될 때
# 또는 교환이 가능할 때(예제3) 바르게 셀 수 없다.
# 요소를 쪼개서 곱하는 게 아니라
# 아예 답을 내고 set으로 중복을 걸러야 한다.
def check(banned_id,user_id):
if len(banned_id)!=len(user_id):
return 0
for idx, letter in enumerate(banned_id):
if letter == '*':
continue
else:
if(letter!=user_id[idx]):
return 0
return 1
def solution(user_id, banned_id):
answer=1
for i in banned_id:
count = 0
for j in user_id:
count+=check(i,j)
print(i,j,check(i,j))
print('최종count',count)
answer*=count
return answer
[소스코드]
# user_id 배열이 작다. -> 노가다로 풀어도 된다.
# 브루트 포스 어떻게? itertools로 banned_id만큼
# 다 뽑아 놓고, 안되는 걸 거르자.
# permutations를 쓰는 이유 : 결국 길이를 맞추고 일대일 대응의 수를 세는 건데
# combinations로 users를 만들면 맞추는 순서에 따라 되기도 하고 아니기도 한다.
# 이를 방지하기 위해 중복 경우 처리는 마지막에 answer에 담을 때 하기.
# 길이가 같은 배열을 zip으로 묶으면 아이터레이터 두 개로 순회할 수 있다!!!
from itertools import permutations
def check(users, banned_id):
if len(users)!=len(banned_id):
return False
else:
for i, j in zip(users,banned_id):
if j == '*':
continue
if i!=j:
return False
return True
def solution(user_id, banned_id):
answer=[]
users_list =permutations(user_id,len(banned_id))
for users in users_list:
count = 0
# zip으로 매칭되는 숫자를 세고, 그게 전체 길이랑 맞으면
# 하나의 일대일 대응을 만들어 내는 것으로 간주
for a, b in zip(users, banned_id):
if check(a,b):
count+=1
if count == len(banned_id):
if set(users) not in answer:
answer.append(set(users))
return len(answer)
[출처]
https://bladejun.tistory.com/49