Posts 6Week 복서 정렬하기 [Python]
Post
Cancel

6Week 복서 정렬하기 [Python]

URL https://programmers.co.kr/learn/courses/30/lessons/85002

문제 설명

  • 복서 선수들의 몸무게 weights와, 복서 선수들의 전적을 나타내는 head2head가 매개변수로 주어집니다. 복서 선수들의 번호를 다음과 같은 순서로 정렬한 후 return 하도록 solution 함수를 완성해주세요.
  • 전체 승률이 높은 복서의 번호가 앞쪽으로 갑니다. 아직 다른 복서랑 붙어본 적이 없는 복서의 승률은 0%로 취급합니다.
  • 승률이 동일한 복서의 번호들 중에서는 자신보다 몸무게가 무거운 복서를 이긴 횟수가 많은 복서의 번호가 앞쪽으로 갑니다.
  • 자신보다 무거운 복서를 이긴 횟수까지 동일한 복서의 번호들 중에서는 자기 몸무게가 무거운 복서의 번호가 앞쪽으로 갑니다.
  • 자기 몸무게까지 동일한 복서의 번호들 중에서는 작은 번호가 앞쪽으로 갑니다.

제한사항

  • 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’입니다.

문제 풀이

목표 : 대결결과 리스트에 [index, 승률, 자기보다 무거운 사람을 이긴 횟수, 나의 몸무게] 순으로 만든다.

  • 승률은 승리횟수 / (승리횟수 + 패배횟수)로 구한다 (N은 승률에 영향을 미치지 않음)
    • 여기서 승률은 N의 횟수는 고려하지않는다. 이것 때문에 분모가 0이 나올수 있으므로 try excpet로 나누어 준다.
  • 내가 승리한 복서의 index를 가져온 후 승리한 복서의 몸무게를 가져와서 나의 몸무게보다 무거운 횟수를 확인한다.
    • 이후 승률이 동점일때 나보다 무거운 사람을 이긴 횟수를 기준으로 삼아야 하기 때문
  • 나의 몸무게를 결과에 저장한다.
    • 2번까지 동점이라면 몸무게가 더 무거운 사람이 우선 순위 이기 때문
  • 모든 복서의 대결결과 리스트를 저장하고, 이를 위의 조건에 맞게 sorted한다.
    • 여러 조건 sorted 방법 lamda x : (x[1], x[2])
  • sorted된 전체 결과에서 index만 따로 추출한다.
    • index가 0부터 시작이기 때문에 +1을 해준다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def solution(weights, head2head):
    answer = []
    total_wins = []
    more_wins = []

    for i in range(len(weights)):
        # 대결 결과를 저장할 리스트 생성
        wins = []
        
        # index 삽입
        wins.append(i)
        
        # 승률 계산 후 삽입
        try :
            win_ratio = head2head[i].count('W') / (head2head[i].count('W') + head2head[i].count('L'))
        except:
            win_ratio = 0
        wins.append(win_ratio)
        
        # 내가 이긴 복서의 index를 가져온 후 상대 복서보다 내 몸무게가 가벼우면(상대방이 무거우면) 횟수를 더한다.
        w_inx = list(filter(lambda x : head2head[i][x] == 'W', range(len(weights))))
        more_win = 0
        for w in w_inx:
            if weights[i] < weights[w]:
                more_win += 1
                
        # 몸무게가 나보다 더 나가는 사람의 승리횟수를 대결결과 리스트에 저장
        wins.append(more_win)
        
        # 나의 몸무게를 대결결과 리스트에 저장
        wins.append(weights[i])
        total_wins.append(wins)
        
    # 모든 결과를 조건에 맞게 sorted 한다.
    total_wins = sorted(total_wins, key = lambda x : (x[1], x[2], x[3]), reverse=True)

    # sorted한 결과의 index만 따로 추출한다.
    for total_win in total_wins:
        answer.append(total_win[0] + 1)

    return answer
1
2
3
weights = [50,82,75,120]
head2head = ["NLWL","WNLL","LWNW","WWLN"]
solution(weights, head2head)
1
[3, 4, 1, 2]
1
2
3
weights = [145,92,86]
head2head = ["NLW","WNL","LWN"]
solution(weights, head2head)
1
[2, 3, 1]
1
2
3
weights = [60,70,60]
head2head = ["NNN","NNN","NNN"]
solution(weights, head2head)
1
[2, 1, 3]
This post is licensed under CC BY 4.0 by the author.