코딩테스트

[파이썬(python)] 2022 카카오 블라인드 공채 신고 결과 받기

고후 2022. 3. 9. 16:34

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

 

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

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

programmers.co.kr

이 문제는 어렵지 않았다. 간단하게 풀었지만

풀면서 어.. 이거 해시 쓰는거네? 

좀더 간단하게 풀수 없나 하는 생각이 들었다.

 

실제 시험 보는것처럼 5시간동안 7문제 풀었어서 풀자마자 넘어갔는데

다 풀었으니깐~~

이제 코드 개선을 해보려고 한다.

 

 

처음 작성한 코드

원래 코드도 나쁘지는 않지만,

id 명단을 입력하는 배열 id_list,

id 별로 신고한 사람을 저장하는 id_report,

id 별로 신고당한 횟수를 저장하는 id_reported,

그리고 마지막으로 정지당한 id를 저장하는 배열 stop_id까지.... 배열을 너무많이 사용했다.

 

def solution(id_list, report, k):
    answer = []
    report = list(set(report))
    
    id_report = [[] for _ in range(len(id_list))]
    #유저가 신고한 id
    id_reported = [0 for _ in range(len(id_list))]
    #유저 별로 신고 당한 횟수
    stop_id = []
    #정지된 id
    
    user_id = ''
    spam_id = ''
    
    for str in report:
        user_id, spam_id = str.split()
        #유저 아이디, 신고당한 아이디
        index = id_list.index(user_id)
        id_report[index].append(spam_id)
        
        spam_index = id_list.index(spam_id)
        id_reported[spam_index] += 1
        
    for i in range(len(id_reported)):
        if id_reported[i] >= k:
            #k번 이상 신고당했을 때 정지됨
            stop_id.append(id_list[i])
    
    for i in id_report:
        count = 0
        for j in i:
            if j in stop_id:
                count += 1
        answer.append(count)
    
    return answer

수정한 코드

신고된 id가 정지됐는지 확인하기 위해 stop_id를 생성했던 것과 달리

신고가 k 번 미만이면 신고를 0으로 리셋했다.

코드가 조금 더 깔끔해지긴 했지만 id의 인덱스를 찾는 연산이 조금 거슬린다.

이제 답지를 확인해보자.

 

def solution(id_list, report, k):
    answer = []
    report = list(set(report)) #중복 제거
    
    id_report = [[] for _ in range(len(id_list))]
    #유저가 신고한 id
    id_reported = [0 for _ in range(len(id_list))]
    #유저 별로 신고 당한 횟수
    
    
    for str in report:
        user_id, spam_id = str.split()
        #유저 아이디, 신고당한 아이디
        index = id_list.index(user_id) #user_id의 인덱스 찾음
        id_report[index].append(spam_id)
        
        spam_index = id_list.index(spam_id) #spam_id의 인덱스 찾음
        id_reported[spam_index] += 1
        
    for i in range(len(id_list)):
        if id_reported[i] < k:
            #k번 이하 신고당하면 신고 취소
            id_reported[i] = 0
    
    for reports in id_report:
        count = 0
        for r in reports:
            #각 신고한 id에 대해 신고한 id가 정지당했을 경우
            if id_reported[id_list.index(r)] != 0:
                count += 1
        answer.append(count)
        
    
    return answer

 

 

답지

 

딕셔너리 자료구조를 활용해서, id 별로 신고당한 횟수를 저장해두고,

신고횟수가 k가 넘어가면

그 id를 신고한 사람의 answer가 1 증가하는 아주 간단한 코드다.

특히 하나의 for문 안에서 report를 split한 다음에 신고당한 id와 신고한 id를 모두 저장했었는데..

for문을 나눠서 신고된 id의 횟수만 증가시키고,

그 다음 for문에서 다시 report를 받아와서 신고한 id가 정지당했을 경우

신고한사람의 answer가 1 증가하는 것

 

그리고 딕셔너리 자료구조 활용.. 그 생각을 못했다.

코드 줄도 간결하고 아주 깔끔하다

 

def solution(id_list, report, k):
    answer = [0] * 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