본문 바로가기
개인 공부/알고리즘 트레이닝

[python] programmers - 신고 결과 받기

by 아메리카노와떡볶이 2022. 9. 2.
728x90

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

 

프로그래머스

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

programmers.co.kr

문제의 구체적인 사항은 위의 링크를 참조하면 됩니당.

 

문제 설명

신입사원 무지는 게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템을 개발하려 합니다. 무지가 개발하려는 시스템은 다음과 같습니다.

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

다음은 전체 유저 목록이 ["muzi", "frodo", "apeach", "neo"]이고, k = 2(즉, 2번 이상 신고당하면 이용 정지)인 경우의 예시입니다.

 

위의 경우 neo와 frodo는 신고를 2번씩 당했으므로 k 이상이기때문에 이용정지 대상자가 됩니다.

따라서 neo와 frodo를 신고한 유저는 제재에 대한 메일을 받을 것이고, 이 횟수를 최종적으로 카운트하는게 목표입니다.

 

muzi는 frodo와 neo를 신고했으므로 2번의 메일을 받고

frodo는 neo를 신고했으므로 1번의 메일을 받고

apeach는 frodo를 신고했으므로 1번의 메일을 받고

neo는 신고대상이 없으므로 0번의 메일을 받습니다.

 

위의 예시에 대한 입출력 예시는 아래와 같습니다.

 

문제 풀이

설명 순서대로 따라가면 쉽게 해결할 수 있습니다. 먼저 구현해야할 사항을 순서대로 정리해봅시다.

 

1. 유저별로 신고당한 횟수를 구합니다.

2. 신고당한 횟수가 k번을 넘는 제재 대상을 색출합니다.

3. 유저별로 몇명의 제재 대상을 신고했는지 count 합니다. 즉 메일받는 횟수를 세아립니다.

 

저는 크게 세단계로 나누어서 문제를 풀이했고, 차례대로 해결해보겠습니다.

 

1. 유저별 신고당한 횟수 구하기

유저별로 신고당한 횟수를 구하기 위해서는 입력으로 주어지는 report 정보를 parsing 해서 신고자와 신고대상자를 구분해야합니다. 즉 "muzi frodo" 라는 문자열을 parsing해서 신고자는 muzi, 신고대상자는 frodo로 구분하는 것입니다.

이때 이 과정을 용이하게 하기위해서 인덱스를 활용하면 좋습니다.

 

먼저 이해를 돕기 위해 위의 예시의 경우를 가정해서 풀이하겠습니다.

muzi, frodo, apeach, neo 4명에게 각 0번부터 3번까지 번호를 부여합니다.

 

그 후 2차원 배열을 활용해서 신고정보를 parsing 합니다. 예시는 아래와 같습니다

 

"muzi frodo" -> 신고자 인덱스 : 0 , 신고대상 인덱스 : 1 -> report_cnt[0][1] = 1

"apeach frodo"->  신고자 인덱스 : 2, 신고대상 인덱스 : 1 -> report_cnt[2][1] = 1

"frodo neo"-> 신고자 인덱스: 1, 신고대상 인덱스 : 3 -> report_cnt[1][3] = 1

 

이렇게 신고정보를 parsing 했다면 각 유저별로 몇번의 신고를 당했는지 횟수를 구합니다.

2차원 배열을 참조해서, 각 유저별 신고 횟수를 카운팅해서 배열에 저장합니다.

 

2. 신고당한 횟수가 k번을 넘는 제재 대상 찾기

1번에서 구한 유저별 신고횟수를 참조해서 신고횟수가 k번을 넘는 유저가 있는지 확인합니다.

 

3. 유저별  메일받는 횟수 카운트

2번에서 구한 제재 대상을 신고한 유저는 메일을 받게됩니다.

즉 유저별로 몇 명의 제재대상을 신고했는지 카운트하면 메일을 받는 횟수를 구할 수 있습니다.

 

문제 풀이 코드

파이썬을 통해 풀이했습니다.

def solution(id_list, report, k):
# 0. 변수 설정 
    n = len(id_list) # 회원 숫자
    report_cnt = [ [0]*n for i in range(n)]
    answer = [0] * n
    cnt = [0] * n

# 1. 유저 별 신고 당한 횟수 구하기

# 유저 번호 부여하기
    dic = {}
    for idx,id in enumerate(id_list):
        dic[id] = idx

# report 정보를 parsing 해서 2차원 배열에 저장 
    for rep in report:
        s = rep.split()
        # s[0] -> 신고자
        # s[1] -> 신고 당한사람

        idx_a = dic[s[0]]
        idx_b = dic[s[1]]
        report_cnt[idx_a][idx_b] = 1

 # 2차원배열을 참조해서 유저별 신고당한 횟수 count    
    for i in range(n):
        for j in range(n):
            cnt[i] += report_cnt[j][i]

    # 2. 제재 대상 찾기 (k번 이상 신고당한 사람 찾기
    for idx,count in enumerate(cnt):
        #제재대상이라면
        if count >= k:
            # 3. 제재대상(idx번째 유저)를 신고한 사람은 메일 횟수 + 1
            for i in range(n):
                if report_cnt[i][idx] == 1:
                    answer[i] += 1

    return answer

728x90

댓글