Development Project

[ Programmers - 06/24 ] - 신고결과받기(Python)_Level1 본문

CodingTest/Programmers

[ Programmers - 06/24 ] - 신고결과받기(Python)_Level1

나를 위한 시간 2022. 6. 24. 13:03
  • 문제링크

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

 

코딩테스트 연습 - 신고 결과 받기

문제 설명 신입사원 무지는 게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템을 개발하려 합니다. 무지가 개발하려는 시스템은 다음과 같습니다. 각 유저는 한 번에 한 명의

programmers.co.kr

 

 

  • 문제

 

 

 

  • 시행착오

꽤 간단해 보였으나... 결론부터말하면 내 마음대로 풀려다가 여러번 시간초과가 났다.

내가 이 문제를 접근할 때 가장 많이한 실수는 문제를 제대로 이해하지 않고 접근했다는 것이다.  문제를 대충 훑고 바로 코드를 풀려고 했어서 이해가 어려운 문제가 아님에도 시간을 많이 소요했던 것 같다. 문제를 잘읽쟈..!

 

 

 

  • 문제 분석

이 문제의 핵심은 

id_list : 신고를 받거나 신고를 한 유저의 전체 아이디 리스트

report : "신고를한사람  신고를받은사람" 으로 이루어진 리스트

k : 실제 신고처리가 되는 신고요청횟수 ==> 이게 충족되야 메일을 보낸다

이 3개의 인자를 받아 

유저별로 신고메일을 받은 횟수를 보내는 문제이다. 같은 사람의 여러번 신고는 1회로 처리한다.

=> 여기서 유저는 신고를한사람이다! (문제를 잘못읽어 여기를 이해못했었음.. 큽)

신고를한사람(유저)의 신고를 받은 사람이 총 k번 이상의 신고를 받은사람이라면 실제 신고처리가 되는데, 이 사람이 신고처리가 되었음을 신고를한사람에게 보내주는 것이다! 

이거를 이해해야 이 문제에 제대로 접근할 수 있다

 

 

 

  • 각 파라미터의 유형 

id_list = ["muzi", "frodo", "apeach", "neo"]

<조건> 2 ≤ id_list의 길이 ≤ 1,000 그리고 1 ≤ id_list의 원소길이 ≤ 10

==> 각 원소는 공백이 없는 문자열이며, 위의 조건을 충족한다.

 

report = ["muzi frodo", "apeach frodo", "frodo neo", "muzi neo", "apeach muzi"]

<조건> 1 ≤ report의 길이 ≤ 200,000 그리고 3  report의 원소길이  21

=> 유저 아이디 문자열 두개가 공백하나로 연결되어있는 문자열로 이루어져있으며, 위의 조건을 충족한다.

 

k=2

<조건> 1 ≤ k ≤ 200, k는 자연수

=> 위의 조건을 충족한다.

 

 

 

 

  • 문제 접근

※ 작성자가 문제를 보고 든 생각을 차례대로 써본 것이다. 이 순번은 정답이 아니며 매번 다른 생각을 해보길 권장한다.

 

1)  report 변수는 공백이 하나 존재하고 앞뒤로 문자열이 있으므로 이를 추출하는 split()함수를 써야한다. 그리고 이를 쓰려면 report요소 하나하나에 접근할 수 있어야하니 반복문 for문이 필요하다

for i in report:
    i.split()[0] # 신고를 한사람
    i.split()[1] # 신고를 받은사람

 

2)  report는 2개의 아이디, id_list는 1개의 아이디로 이루어져있기 때문에, report변수와 id_list변수는 같이 엮어서 사용이 가능하다. id_list는 아이디의 순번을 나타낼 수 있고, report는 이 아이디(유저)간의 action(신고)을 보여줄 수 있으니 서로 인덱스가 되거나 값이되는 관계로 이를 이어줄 수 있다.

id_list = ["A", "B", "C"]
report = ["A B", "A C"]
report[0].split()[0]   # A B문자열에서 A
id_list.index(report[0].split()[0])   # A를 값으로가지는 id_list의 인덱스 : 0

 

3) 문제의 조건에서 같은 사람이 같은 대상에게 신고를 여러번 했을 경우, 1회로 계산한다고 한다. 이는 중복을 제거하라는 말인데, 위 파라미터들은 다 list형태이니, set()을 통해 집합으로 변환했다가 list로 가져오면 중복이 자연스레 제거된다.

report=list(set(report))

 

4) 결과를 출력하기 위해서는 한 사람이 누구를 신고했는지에 대한 정보를 얻기 쉬워야한다. 리스트로 하려면 2중리스트가 되므로 비효율적이기 때문에(보통 이중 반복문을 사용하게 되므로) 딕셔너리가 적합하다고 생각했다.

reports = {x:0 for x in id_list}   # key : id_list의 한 항목 / value : 0

 

 

 

  • 최종코드
def solution(id_list, report, k):
    answer = [0 for i in range(len(id_list))]
    reports = {x:0 for x in id_list}

    for i in set(report):
        reports[i.split()[1]]+=1
    
    for i in set(report):
        if reports[i.split()[1]]>=k:
            answer[id_list.index(i.split()[0])]+=1
            
    return answer

 

Comments