문제
https://school.programmers.co.kr/learn/courses/30/lessons/42889
오천성 게임의 각 스테이지 난이도를 조절하기 위해 플레이어들의 진행상황으로부터 실패율을 구하는 문제
N개의 스테이지가 있고 각 유저의 진행도를 나타내는 stages가 있을 때 스테이지를 실패율이 높은 순으로 정렬하기
전략
01. groupby
각 플레이어의 진행도를 정렬하고 itertools 라이브러리의 groupby를 이용해 진행한 스테이지 별로 묶은 뒤, 각각의 개수를 세면 전체 플레이어 중에서 몇 명의 플레이어가 해당 스테이지에 머물러 있는지 알 수 있다. 그렇게 되면 실패율 = (i번째 스테이지) / (i번째 스테이지 ~ 마지막)이 되므로 각 스테이지의 실패율을 구할 수 있다.
풀이
from itertools import groupby
def solution(N, stages):
num_of_clear = [0] * (N+2)
failure_rate = {}
stages.sort()
for i, v in groupby(stages):
num_of_clear[i] = len(list(v))
for i in range(1, N + 1):
if sum(num_of_clear[i:]) == 0:
failure_rate[i] = 0
else:
failure_rate[i] = num_of_clear[i] / sum(num_of_clear[i:])
return [i for i, j in sorted(failure_rate.items(), key=lambda x: (-x[1]))]
stages를 오름차순으로 정렬한 뒤 groupby로 묶고 각각을 num_of_clear 리스트에 넣어주었다. num_of_clear 리스트는 0 ~ N + 2까지의 길이를 나타내는데, 이유는 두가지다. 하나는 0부터 세기 번거로워서 1로 맞춰준 것이며, N + 1이 아니라 N + 2인 이유는 N = 5 즉 5스테이지까지 있을 경우 5스테이지를 클리어한 플레이어는 stages에서 6으로 나타나기 때문에 그 숫자까지 넣어주기 위해서다.
이제 각 스테이지 별로 클리어하지 못했거나 전부 클리어한 플레이어의 수가 나왔으므로 다시 num_of_clear리스트를 for문으로 순회하면서 실패율을 구한다. 이때, stages = [3, 0, 0, 0]인 경우 i = 1일 때부터 sum(num_of_clear[i:])가 0이 되므로 이를 제한하기 위해 sum(num_of_clear[i:]) == 0일 때 실패율은 0이라는 단서를 주었다.
각각의 실패율은 failure_rate 딕셔너리에 넣어주었다. 리스트가 아닌 이유는 추후에 실패율 순으로 정렬할 때 인덱스가 0인 경우를 제외하기 위해서다.
이제 마지막으로 실패율을 나타내는 failure_rate 딕셔너리를 lambda함수를 이용해 value순으로 내림차순 정렬하고 key값만을 뽑아내서 풀었다. '만약 실패율이 같은 스테이지가 있다면 작은 번호의 스테이지가 먼저 오도록 하면 된다.'라는 조건을 충족하기 위해 정렬할 때 두번째 조건이 없으면 동일한 value값에서 앞선 값이 먼저 정렬된다는 점을 이용했다.
'프로그래밍 > 문제풀이' 카테고리의 다른 글
[코딩테스트] 해시 - 전화번호 목록 (0) | 2023.07.28 |
---|---|
[코딩테스트] 힙(Heap) - 더 맵게 (0) | 2023.07.25 |
[코딩테스트] 탐욕법(Greedy) - 단속카메라 (0) | 2023.07.20 |
[코딩테스트] 2022 KAKAO BLIND RECRUITMENT - 주차 요금 계산 (0) | 2023.07.20 |
[코딩테스트] 2018 KAKAO BLIND RECRUITMENT - 캐시 (0) | 2023.07.19 |