[알고리즘] 게시판 불량 이용자 신고결과 받기

전도운·2024년 8월 3일
0
post-custom-banner

프로그래머스 코딩테스트 연습 - 신고 결과 받기 문제 (바로가기)

신입사원 무지는 게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템을 개발하려 합니다. 무지가 개발하려는 시스템은 다음과 같습니다.
각 유저는 한 번에 한 명의 유저를 신고할 수 있습니다.
신고 횟수에 제한은 없습니다. 서로 다른 유저를 계속해서 신고할 수 있습니다.
한 유저를 여러 번 신고할 수도 있지만, 동일한 유저에 대한 신고 횟수는 1회로 처리됩니다.
k번 이상 신고된 유저는 게시판 이용이 정지되며, 해당 유저를 신고한 모든 유저에게 정지 사실을 메일로 발송합니다.
유저가 신고한 모든 내용을 취합하여 마지막에 한꺼번에 게시판 이용 정지를 시키면서 정지 메일을 발송합니다.

이용자의 ID가 담긴 문자열 배열 id_list, 각 이용자가 신고한 이용자의 ID 정보가 담긴 문자열 배열 report, 정지 기준이 되는 신고 횟수 k가 매개변수로 주어질 때, 각 유저별로 처리 결과 메일을 받은 횟수를 배열에 담아 return 하도록 solution 함수를 완성해주세요.

  • 최초 풀이

    • (1단계) 신고받은 횟수와 신고한 id를 넣을 딕셔너리 생성

    • (2단계) 신고받은 횟수와 신고한 id(중복제거)를 딕셔너리에 넣어줌

    • (3단계) k번 이상 신고받은 아이디만 남김

    • (4단계) 아이디별 메일 수신 횟수 카운트

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

    # 신고받은 횟수와 신고한 id를 넣을 딕셔너리 생성
    for id in id_list:
        reported_id[id] = 0
        report_id[id] = list()

    # 신고받은 횟수와 신고한 id(중복제거)를 딕셔너리에 넣어줌
    for rep in report:
        rep_id, reped_id = rep.split(' ')
        if report_id[reped_id].count(rep_id) == 0:
            reported_id[reped_id] += 1
            report_id[reped_id].append(rep_id)
   
    # k번 이상 신고받은 아이디만 남김
    reported_id = {reped_id : count for reped_id, count in reported_id.items() if count >= k}

    # 아이디별 메일 수신 횟수 카운트
    for reped_id in reported_id.keys():
        for id in report_id[reped_id]:
            answer[id_list.index(id)] += 1
          
    return answer
  • 알고리즘 효율화를 위해 Chat GPT에 개선점을 물었고 아래와 같은 답을 얻었다.

    • 문제에서는 id_list에 모든 사용자가 존재한다고 정해두었지만, id_list에 존재하지 않는 사용자가 신고된 경우까지 고려해야 한다는 점이 인상깊었다.

코드를 개선할 수 있는 몇 가지 점을 제안해 드리겠습니다. 여기에는 코드의 효율성, 가독성, 그리고 가능한 예외 처리 등이 포함됩니다.

중복 방지와 데이터 구조 선택
현재는 각 사용자가 신고한 ID를 리스트에 저장하고 중복 여부를 리스트의 count 메서드로 확인합니다. 대신, 신고한 사용자를 set으로 저장하면 중복 확인이 훨씬 효율적입니다.

불필요한 반복문 제거
reported_id 딕셔너리를 report_id 딕셔너리와 병합할 수 있습니다. 이는 단일 반복문을 통해 처리할 수 있습니다.

코드의 가독성 향상
변수 이름을 좀 더 직관적으로 변경하고, 불필요한 변수 사용을 줄일 수 있습니다.

예외 처리
현재 코드는 id_list에 존재하지 않는 사용자가 신고된 경우를 처리하지 않습니다. 그런 경우를 처리할 수 있는 로직을 추가하는 것이 좋습니다.

  • 위 개선점을 반영해 수정한 코드는 아래와 같다.
def solution(id_list, report, k):
    answer = [0] * len(id_list)
    report_count = {id: 0 for id in id_list}
    reports_received = {id: set() for id in id_list}

    for rep in report:
        reporter, reported = rep.split()
        if reporter not in reports_received[reported]:
            reports_received[reported].add(reporter)
            report_count[reported] += 1
   
    for reported, count in report_count.items():
        if count >= k:
            for reporter in reports_received[reported]:
                answer[id_list.index(reporter)] += 1

    return answer
profile
의미 있는 한걸음을 추구합니다.
post-custom-banner

0개의 댓글