[프로그래머스_Lv1] 복서 정렬하기

Lee, Chankyu·2021년 10월 10일
0
post-thumbnail
post-custom-banner

복서 정렬하기

문제 링크

문제 설명
복서 선수들의 몸무게 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'입니다.

나의 풀이

def solution(weights, head2head):
    answer = []
    player_record = []
    for i in range(len(head2head)):
        match_count = 0  #경기 수
        win = 0          #승리 횟수
        superwin = 0     #본인 보다 무거운 상대한테 승리한 횟수
        for j in range(len(head2head)):
            if head2head[i][j] == "W" or head2head[i][j] == "L":
                match_count+=1
                if head2head[i][j] == "W":
                    win+=1
                    if weights[i] < weights[j]:
                        superwin+=1
        if match_count != 0:
            win_rate = (win/match_count)*100 # 승률 계산
        else: 
            win_rate = 0
        player_record.append((win_rate, superwin, weights[i], i+1))
    
    player_record = sorted(player_record, key=lambda x:(x[0],x[1],x[2],-x[3]), reverse=True)
    
    return [i[3] for i in player_record] 
  • 우선 마지막에 순위 결정의 기준대로 정렬할 수 있도록 문제에서 정해준 기준의 우선순위 순서대로 계산과 정렬하는 것이 포인트다.
    승률 계산시 경기를 치르지 않은 상대는 포함되지 않도록 조건문을 작성하여 match_count 변수에 경기 수를 카운트 하였다. 그리고 이중조건문으로 win 승리 횟수를 카운트하였고 추가적으로 삼중 조건문으로 무게를 조건으로 작성하여 superwin 을 카운트 하였다. 이렇게 카운트 된 변수들을 사용하여 승률을 계산후, player_record 변수에 답안 도출에 필요한 기준들(승률, 무게, 무거운상대이긴횟수, 넘버)을 하나의 요소로 append 하였다.
    처음엔 매우 어렵게 느껴졌지만 여기까지는 조금만 생각하면 무난하게 할 수 있었느나 내가 정렬한 데이터로 최종 답을 도출해내는 것이 의외로 난관이었다. sorted() 함수와 lambda 함수의 적용이 익숙치가 않았다. 특히 sorted() 함수의 사용 목적은 지난 학습을 통해 알고 있었으나 lambda를 이용한 value 정렬은 잘 몰랐었다. 추가 학습을 통해 해결하긴 하였으나 추후 이와 관련하여 추가 학습 및 블로그 작성을 진행하겠다.

다른 사람의 풀이

def solution(weights, head2head):
    answer = []
    player_num = len(weights)
    info = [[0,0,-(weights[i]),i+1]for i in range(player_num)]

    def calcul(p, s):
        w = 0
        n = player_num
        weight = p[2]

        #전적을 보고 1, 2 경우를 수정한다.
        for i in range(len(s)):

            #전적이 승리일 시 승리 횟수 증가
            if s[i] == 'W':
                w += 1

                #체급극복을 했을 시 p info의 체급극복수 증가
                if weight > -(weights[i]):
                    p[1] -= 1

            #비기면 총전적 1감소
            elif s[i] == 'N':
                n -= 1

        if n == 0:
            p[0] = 0
            return
        p[0] = -w/n

    for i in range(player_num):
        calcul(info[i], head2head[i])

    return [i[3] for i in sorted(info)]
profile
Backend Developer - "Growth itself contains the germ of happiness"
post-custom-banner

0개의 댓글