라떼는말이야

[프로그래머스 위클리 챌린지] 6주차_복서 정렬하기 본문

알고리즘/코딩 테스트

[프로그래머스 위클리 챌린지] 6주차_복서 정렬하기

MangBaam 2021. 9. 6. 11:42
반응형

오늘은 6번째로 풀이했네요.

도움이 되셨다면 "MANGBAAM" 좋아요 부탁드려요~


 

문제 설명

복서 선수들의 몸무게 weights와, 복서 선수들의 전적을 나타내는 head2head가 매개변수로 주어집니다. 복서 선수들의 번호를 다음과 같은 순서로 정렬한 후 return 하도록 solution 함수를 완성해주세요.

  1. 전체 승률이 높은 복서의 번호가 앞쪽으로 갑니다. 아직 다른 복서랑 붙어본 적이 없는 복서의 승률은 0%로 취급합니다.
  2. 승률이 동일한 복서의 번호들 중에서는 자신보다 몸무게가 무거운 복서를 이긴 횟수가 많은 복서의 번호가 앞쪽으로 갑니다.
  3. 자신보다 무거운 복서를 이긴 횟수까지 동일한 복서의 번호들 중에서는 자기 몸무게가 무거운 복서의 번호가 앞쪽으로 갑니다.
  4. 자기 몸무게까지 동일한 복서의 번호들 중에서는 작은 번호가 앞쪽으로 갑니다.

제한사항

  • weights의 길이는 2 이상 1,000 이하입니다.
    • weights의 모든 값은 45 이상 150 이하의 정수입니다.
    • weights[i] 는 i+1번 복서의 몸무게(kg)를 의미합니다.
  • head2head의 길이는 weights의 길이와 같습니다.
    • head2head의 모든 문자열은 길이가 weights의 길이와 동일하며, 'N', 'W', 'L'로 이루어진 문자열입니다.
    • head2head[i] 는 i+1번 복서의 전적을 의미하며, head2head[i][j]는 i+1번 복서와 j+1번 복서의 매치 결과를 의미합니다.
      • 'N' (None)은 두 복서가 아직 붙어본 적이 없음을 의미합니다.
      • 'W' (Win)는 i+1번 복서가 j+1번 복서를 이겼음을 의미합니다.
      • 'L' (Lose)는 i+1번 복사가 j+1번 복서에게 졌음을 의미합니다.
    • 임의의 i에 대해서 head2head[i][i] 는 항상 'N'입니다. 자기 자신과 싸울 수는 없기 때문입니다.
    • 임의의 i, j에 대해서 head2head[i][j] = 'W' 이면, head2head[j][i] = 'L'입니다.
    • 임의의 i, j에 대해서 head2head[i][j] = 'L' 이면, head2head[j][i] = 'W'입니다.
    • 임의의 i, j에 대해서 head2head[i][j] = 'N' 이면, head2head[j][i] = 'N'입니다.

입출력 예

입출력 예

입출력 예 #1

  • 다음은 선수들의 정보를 나타낸 표입니다.
  • 본문에 서술된 우선순위를 따라 [3,4,1,2] 를 return 합니다.

입출력 예 #2

  • 다음은 선수들의 정보를 나타낸 표입니다.

  • 본문에 서술된 우선순위를 따라 [2,3,1] 을 return 합니다.

입출력 예 #3

  • 다음은 선수들의 정보를 나타낸 표입니다.

  • 본문에 서술된 우선순위를 따라 [2,1,3] 을 return 합니다.

나의 풀이

이 문제는 정렬 문제이다. 주어진 데이터에서 적절히 정보를 뽑아내어 정렬하면 된다.

아이디어

  • 각 선수들의 정보를 info 리스트에 담는다.
    • 자신의 번호, 자신의 무게, 승률, 자신보다 무거운 복서를 이긴 횟수를 저장한다.
  • 각 정보를 승률, 무거운 놈 이긴 횟수, 자신의 무게, 자신의 번호 순으로 정렬한다.
    • 이때 모두 내림차순 정렬이지만 자신의 번호는 오름차순 정렬이다.
  • 정렬된 결과에서 번호+1을 return한다. (인덱스는 0부터 시작하기 때문)

 

소스코드

def solution(weights, head2head):
    info = []
    w = len(weights)
    for p in range(w):
        high = [i for i in range(w) if weights[i]>weights[p]] # 더 무거운 사람 인덱스
        over = len([info for info in high if head2head[p][info]=="W"]) # 더 무거운 사람 이긴 수
        rate = 0 if not (w-head2head[p].count("N")) else head2head[p].count("W")/(w-head2head[p].count("N"))
        info.append((p, weights[p], rate, over)) # 번호, 자기무게, 승률, 무거운복서 이긴 횟수
    info = sorted(info, key=lambda x: (x[2], x[3], x[1], -x[0]), reverse=True)
    return [num[0]+1 for num in info]

high에는 자신보다 더 무거운 사람의 인덱스를 저장한다.

over에는 high의 정보를 토대로 전적에서 "W"인 것을 센다. 그러면 자신보다 더 무거운 사람을 이긴 횟수를 뽑을 수 있다.

rate는 승률이다. 전체 전적에서 모두 "N"일 때는 0을 저장하고, 그렇지 않다면 [이긴 횟수 ÷ "N"을 제외한 전적] 이 승률이 된다. (0으로 나눌 수 없으므로 모두 "N"인 경우를 먼저 처리했다)

마지막으로 info에 번호, 자기무게, 승률, 무거운 복서를 이긴 순서를 튜플로 묶어서 저장한다.

 

sorted로 승률, 무거운 복서 이긴 횟수, 자기 무게, 번호 순으로 정렬한 후 번호 + 1을 담은 리스트를 리턴하면 답이 된다.

 

테스트 결과

반응형
Comments