BOJ/Python

[프로그래머스] 신고 결과 받기 파이썬

띵지니어 2023. 11. 20. 19:55

https://school.programmers.co.kr/learn/courses/30/lessons/92334

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

문제 보기

 

내 코드

from collections import defaultdict

def solution(id_list, report, k):
    answer = [0] * len(id_list)

    report_count = defaultdict(int)
    for i in set(report):
        report_count[i.split()[1]] += 1
    
    filtered_set = {key for key, value in report_count.items() if value >= k}

    result_dict = defaultdict(list)
    for i in set(report):
        a, b = i.split()
        result_dict[a].append(b)
        
    for i, user in enumerate(id_list):
        answer[i] = sum(1 for target in result_dict[user] if target in filtered_set)

    return answer

 

Review

 

제가 생각했던 알고리즘은 이러합니다.

1. k 번 이상 신고된 회원의 리스트를 만든다.

2. report를 순회하면서 k 번이상 신고된 회원이 있는지 판별해서 개수를 센다.

 

구현 내용

 

문제에서 제시된 입출력 예로 설명하겠습니다.

id_list = ["muzi", "frodo", "apeach", "neo"]
report = ["muzi frodo","apeach frodo","frodo neo","muzi neo","apeach muzi"]
k = 2

일단 answer는 결과를 나타내기 위한 리스트입니다.
길이가 회원 개수인 리스트를 0으로 초기화해줍니다.
answer = [0, 0, 0, 0]

defaultdict을 사용해서 각 회원이 몇 번 신고되었는지 확인합니다.
⭐️ defaultdict 이 모른다면 5분만 읽어봐도 이해할 수 있을 거예요!
defaultdict 이해하기

report_count = defaultdict(int)
for i in set(report):
    report_count[i.split()[1]] += 1
    
# {'frodo': 2, 'muzi': 1, 'neo': 2}

이때 set(report)를 한 이유는 똑같은 회원이 똑같은 회원을 신고하는 경우를 없애야 하기 때문이다.

 

 

여기서 딕셔너리의 value 값이 k (즉 예제에서는 2) 이상인 원소만 필터링 해줍니다.

filtered_set = {key for key, value in report_count.items() if value >= k}

# {'neo', 'frodo'}

 

 

 

이후 저는 누가 누구를 신고했는지 알기 위해 리스트를 또 만들어주었습니다.

result_dict = defaultdict(list)
for i in set(report):
    a, b = i.split()
    result_dict[a].append(b)
    
# {'muzi': ['frodo', 'neo'], 'apeach': ['frodo', 'muzi'], 'frodo': ['neo']}

 

 

 

마지막으로 id_list와, result_dict을 순회하면서 result_dict[user]에 filtered_set 이 있는 개수를 더해주면 됩니다.

원래 2중 for 문인데 리스트컴프리헨션으로 줄였습니다.

for i, user in enumerate(id_list):
        answer[i] = sum(1 for target in result_dict[user] if target in filtered_set)
        
# [2, 1, 1, 0]

 

 

저의 설명이 부실할 수도 있어서 마지막 부분만 그림으로 설명하겠습니다.

다양한 많은 변수(리스트, 딕셔너리) 들을 사용했는데 그것들을 사용하지 않고도, 충분히 구현할 수 있지만 좀 더 눈으로 보이는 구현을 하기 위해 사용을 하였습니다.

 

이해가 안 되는 부분을 댓글로 달아주시면 설명드리겠습니다.