관리 메뉴

커리까지

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

알고리즘/풀이

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

목표는 커리 2021. 10. 17. 15:15
728x90
SMALL
문제 설명

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


입출력 예
weights head2head result
[50,82,75,120] ["NLWL","WNLL","LWNW","WWLN"] [3,4,1,2]
[145,92,86] ["NLW","WNL","LWN"] [2,3,1]
[60,70,60] ["NNN","NNN","NNN"] [2,1,3]

입출력 예 설명

입출력 예 #1

  • 다음은 선수들의 정보를 나타낸 표입니다.
선수 번호 vs 1번 vs 2번 vs 3번 vs 4번 승률 자기보다 무거운 복서를 이긴 횟수 몸무게
1번 - 패배 승리 패배 33.33% 1회 50kg
2번 승리 - 패배 패배 33.33% 0회 82kg
3번 패배 승리 - 승리 66.66% 2회 75kg
4번 승리 승리 패배 - 66.66% 0회 120kg
  • 본문에 서술된 우선순위를 따라 [3,4,1,2] 를 return 합니다.

입출력 예 #2

  • 다음은 선수들의 정보를 나타낸 표입니다.
선수 번호 vs 1번 vs 2번 vs 3번 승률 자기보다 무거운 복서를 이긴 횟수 몸무게
1번 - 패배 승리 50% 0회 145kg
2번 승리 - 패배 50% 1회 92kg
3번 패배 승리 - 50% 1회 86kg
  • 본문에 서술된 우선순위를 따라 [2,3,1] 을 return 합니다.

입출력 예 #3

  • 다음은 선수들의 정보를 나타낸 표입니다.
선수 번호 vs 1번 vs 2번 vs 3번 승률 자기보다 무거운 복서를 이긴 횟수 몸무게
1번 - - - 0% (무전적) 0회 60kg
2번 - - - 0% (무전적) 0회 70kg
3번 - - - 0% (무전적) 0회 60kg
  • 본문에 서술된 우선순위를 따라 [2,1,3] 을 return 합니다.

제출답안

def solution(weights, head2head):
    answer = {}
    for idx, values in enumerate(zip(weights, head2head)):
        win_cnt = values[1].count('W')
        lose_cnt = values[1].count('L')
        try:
            per = win_cnt / (lose_cnt + win_cnt) * 100
        except:
            per = 0
        weight_cnt = 0
        for idx2, text in enumerate(values[1]):
            if text == 'W':
                if values[0] < weights[idx2]:
                    weight_cnt += 1
        answer[idx + 1] = [per, weight_cnt, values[0], idx + 1]
    answer = sorted(answer.items(), key=(lambda x: (-x[1][0], -x[1][1], -x[1][2], x[1][3])))
    answer = [i[0] for i in answer]
    return answer
  1. 항상 이중 for문을 사용하고 싶지 않지만 그렇지 않고선 딱히 다른 방법이 없어 보였다.
  2. 우선 몸무게와 승패여부를 같이 받아온다.
    1. 승패 문자열에서 승리와 패배의 개수를 구하고 승률을 구한다.
    2. 0과 0을 나누면 오류가 나이때문에 try, except를 해줘서 오류를 피한다.
  3. 그 다음에 승리하였을 때 몸무게를 비교하기 위해 두번째 for문을 돌린다.
    1. 지금 선수의 승패문자열에서 W가 들어오면 해당 index의 선수와 몸무게를 비교해서 카운트한다.
  4. 마지막으로 해당 선수의 값으로 승률, 몸무게 비교 여부 승패캐수, 몸무게, 번호를 리스트를 만든다.
  5. 딕셔너리를 값으로 정렬하고 0번째부터 정렬하기 위하여 위에서 저장할 때 해당 순으로 저장하였기에 내림차순은 -를 붙이고 아닌건 오름차순은 그대로 진행한다.
  6. 마지막으로 정렬된 리스트에서 번호만 다시 빼와서 return한다.
728x90
LIST
Comments