[algorithm][python] 프로그래머스 실패율

oznni·2021년 6월 23일
0
post-thumbnail

문제

2019 KAKAO BLIND RECRUITMENT | 실패율

실패율

스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수

제한사항

  • stages에는 1 이상 N + 1 이하의 자연수가 담겨있다.
  • 각 자연수는 사용자가 현재 도전 중인 스테이지의 번호를 나타낸다.
  • 단, N + 1 은 마지막 스테이지(N 번째 스테이지) 까지 클리어 한 사용자를 나타낸다.
  • 만약 실패율이 같은 스테이지가 있다면 작은 번호의 스테이지가 먼저 오도록 하면 된다.
  • 스테이지에 도달한 유저가 없는 경우 해당 스테이지의 실패율은 0 으로 정의한다.

입출력 예

Nstagesresult
5[2, 1, 2, 6, 2, 4, 3, 3][3,4,2,1,5]
4[4,4,4,4,4][4,1,2,3]

입출력 예 #1

1번 스테이지에는 총 8명의 사용자가 도전했으며, 이 중 1명의 사용자가 아직 클리어하지 못했다. 따라서 1번 스테이지의 실패율은 다음과 같다.

  • 1 번 스테이지 실패율 : 1/8
    2번 스테이지에는 총 7명의 사용자가 도전했으며, 이 중 3명의 사용자가 아직 클리어하지 못했다. 따라서 2번 스테이지의 실패율은 다음과 같다.

  • 2 번 스테이지 실패율 : 3/7
    마찬가지로 나머지 스테이지의 실패율은 다음과 같다.

  • 3 번 스테이지 실패율 : 2/4

  • 4번 스테이지 실패율 : 1/2

  • 5번 스테이지 실패율 : 0/1

각 스테이지의 번호를 실패율의 내림차순으로 정렬하면 다음과 같다.

  • [3,4,2,1,5]

입출력 예 #2

모든 사용자가 마지막 스테이지에 있으므로 4번 스테이지의 실패율은 1이며 나머지 스테이지의 실패율은 0이다.

  • [4,1,2,3]

문제 풀이

def solution(N, stages):
    frate = []
    sum = stages.count(N+1) # 실패율의 분모, 상위 스테이지에 도달한 플레이어 수를 누적할 변수

    for i in reversed(range(N)):
        stage = i+1 # 해당 스테이지
        count = stages.count(stage) # 실패율의 분자, 해당 스테이지에 도달한 플레이어 수
        sum += count
        
        if sum != 0: # 실패율의 분모가 0이 아닌 경우
            frate.append([count/sum, stage]) # [실패율, 스테이지]
        else: # 실패율의 분모가 0인 경우 (스테이지에 도달한 유저가 없는 경우)
            frate.append([0, stage])

    frate = sorted(frate, key = lambda x : (-x[0], x[1])) # 실패율 내림차순, 실패율이 동일한 경우 인덱스 오름차순 정렬
    return [frate[i][1] for i in range(N)]
  1. 실패율 구하기
    1.1. count = stages.count(stage)stages : 리스트에서 해당 스테이지의 빈도수를 카운트 해서 실패율의 분자 계산
    1.2. sum += count : 현재 스테이지 기준, 모든 상위 스테이지에 도달한 플레이어 수에 현재 스테이지에 도전 중인 플레이어 수를 누적해서 실패율의 분자를 계산
    1.3. frate.append([count/sum, stage]) : 실패율과 해당 스테이지 번호를 리스트로 묶어 저장 (2번의 정렬을 위함)
    1.3. for i in reversed(range(N)) : 이때 상위 스테이지의 플레이어 수부터 누적해서 구할 것이기 때문에 반복문을 거꾸로 돌림(스테이지 5에 도달한 플레이어는 스테이지 1,2,3,4를 이미 도달했고, 이런 패턴으로 각 스테이지가 반복되기 때문에 하위 스테이지에 누적해야함)

  2. 실패율 정렬하기
    frate = sorted(frate, key = lambda x : (-x[0], x[1])) :
    조건에 따라 실패율 내림차순(-x[0]), 실패율이 동일한 경우 인덱스 오름차순(x[1]) 정렬한다.

    lambda(람다)
    이름이 없는 함수로, 코드의 간결함 및 메모리 절약이 장점이다.

    # lambda 인자 : 표현식
    >> (lambda x,y: x + y)(10, 20)
    30

  • 추가(21/6/24)

    여기서 적용해본 lambda를 문자열 내 마음대로 정렬하기에서 적용해봤다.

    각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하되 인덱스 n의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치

  def solution(strings, n):
      return sorted(strings, key = lambda x : (x[n], x))
  # 테스트 코드
  print(solution(["sun", "bed", "car"], 1)) # ["car", "bed", "sun"]
  print(solution(["abce", "abcd", "cdx"], 2)) # ["abcd", "abce", "cdx"]

발생한 문제점 및 해결방안

처음에 런타임에러가 발생했는데 그 이유는 스테이지에 도달한 유저가 없는 경우 실패율의 분모가 0이 되기 때문에 발생했던 것이다.
아래와 같은 if문으로 분모가 0이 아닌 경우에만 실패율을 계산하도록 코드를 수정해서 해결했다.

   if sum != 0: # 실패율의 분모가 0이 아닌 경우
            frate.append([count/sum, stage]) # [실패율, 스테이지]
        else: # 실패율의 분모가 0인 경우 (스테이지에 도달한 유저가 없는 경우)
            frate.append([0, stage])
profile
Android Developer.

0개의 댓글

관련 채용 정보