[Programmers/Lv. 1] 신고 결과 받기 (2022 KAKAO BLIND RECRUITMENT, Python)

2023. 8. 8. 16:51Algorithm

📎 링크


 

프로그래머스

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

programmers.co.kr

 

 

🤔 문제설명, 제한사항, 입출력 예


아래 주어진 조건과 같이 게시판 불량 이용자를 신고하고, 처리 결과를 메일로 발송하는 시스템을 개발하라는 문제이다.

조건 1. 각 유저는 한 번에 한 명의 유저만을 신고할 수 있다.
한 유저를 여러 번 신고하거나, 서로 다른 유저를 계속해서 신고하거나 같은 신고 횟수에 제한은 없다. 
단, 한 유저를 여러 번 신고한 경우에 신고 횟수는 1회로 인정된다. (무지->네오, 무지->네오, 무지->네오 3번을 신고해도 처리는 1회)

조건 2. 매개변수로 주어지는 k번 이상 신고된 유저는 게시판 이용이 정지된다.
이때, 신고된 유저를 신고했던 모든 유저에게 정지 사실이 메일로 발송된다. 우리가 구해야 할 것은 바로 이 부분.
각 유저별로 처리 결과 메일을 받는 횟수를 담은 배열을 구하라는 문제이다.

 

 

🤔 내가 생각한 풀이 과정


나는 유저별로 신고당한 횟수를 먼저 체크하고, 그 횟수가 k 이상인 ID를 신고한 유저를 다시 찾아 리스트의 카운트를 올려주자고 생각했다.
조금 복잡한가?
이 과정을 천천히 따라가면서 설명할 텐데, 과정을 수행해 주기 위해 필요한 작업이 있었다.

우선, 주어진 report에서 중복된 값을 제거하는 과정이 필요하다고 생각했다.
조건 1에서 "한 유저를 여러 번 신고한 경우에 신고 횟수는 1회로 인정된다."라고 언급되어 있기 때문이다.
report 리스트를 집합 자료형으로 바꿔주면 자연스럽게 중복된 신고 데이터는 1회로 만들어졌다.

두번째는, 신고한 유저와 신고당한 유저를 구분할 필요가 있었다.
이 부분은 report에서 중복된 값을 제거한 집합 자료형을 반복문에 넣어, split(" ") 함수를 이용했다. 이렇게 하면 인덱스 0에는 신고 "한" 유저가, 인덱스 1에는 신고 "당한" 유저가 구분돼서 반환될 수 있었다.

[['frodo', 'neo'], ['apeach', 'muzi'], ['muzi', 'neo'], ['muzi', 'frodo'], ['apeach', 'frodo']]

 

이제 처음부터 풀이과정을 따라가보자.
먼저 유저별로 신고당한 횟수를 확인해야 한다. 그래야 나중에 k 이상 신고당한 유저를 구분할 수 있을 것이다.
유저별로 신고당한 횟수는 check_dic이라는 딕셔너리 변수를 이용해서 확인했다. -> 딕셔너리 형태 = {유저 이름: 신고당한 횟수}
신고당한 횟수는 인덱스 1로 구할 수 있으니, 반복하면서 해당 유저 이름이 나온 경우 Value값을 1씩 증가시켜 주자.

{'muzi': 1, 'frodo': 2, 'apeach': 0, 'neo': 2}

 

이제 다시 report를 반복하면서, 이번에는 신고당한 횟수가 k 이상인 유저를 신고했을 경우에, 메일을 받을 횟수를 저장한 리스트 answer의 값을 1씩 증가시켜 주자.
이게 무슨 말이냐면, ["muzi", "frodo"]라는 애가 반복문에 들어왔다고 가정해 보자.
그럼 먼저 frodo가 check_dic 안에 k번 이상 신고를 당한 유저인지 확인을 하고,
만약 k번 이상 신고를 당해 정지 대상자인 유저라면, muzi는 처리 결과 메일을 받아야 하는 대상자인 유저이므로 인덱스에 맞게 answer 리스트의 값을 1 증가시키는 것이다. 이때 인덱스의 값은 id_list.index(반복 리스트[0])으로 찾아줄 수 있겠다.

 

 

👨‍💻 내 코드


def solution(id_list, report, k):    
    # 처리 결과 메일이 갈 횟수 -> 최종 return 리스트
    answer = [0] * len(id_list)
    
    # 신고당한 카운트를 체크할 리스트
    check_dic = {x: 0 for x in id_list}
    
    # 중복 리스트 제거, 리포트를 반복하면서 신고당한 횟수 체크
    for ch in [r.split(" ") for r in set(report)]:
        check_dic[ch[1]] += 1
        
    # 중복 리스트 제거, 리포트를 반복하면서 신고 횟수가 k 이상인 유저를 신고한 경우에 answer 카운트를 증가
    for ch in [r.split(" ") for r in set(report)]:
        if check_dic[ch[1]] >= k:
            answer[id_list.index(ch[0])] += 1        
            
    return answer