관리 메뉴

솜씨좋은장씨

[Programmers] 위클리 챌린지 6주차 - 복서 정렬하기 (Python) 본문

Programming/코딩 1일 1문제

[Programmers] 위클리 챌린지 6주차 - 복서 정렬하기 (Python)

솜씨좋은장씨 2021. 9. 6. 22:58
728x90
반응형

코딩 1일 1문제! 오늘의 문제는 프로그래머스의 위클리 챌린지 6주차 문제인 복서 정렬하기 문제 입니다.

복서 정렬하기 문제를 파이썬을 활용해 풀이해보았습니다.

 

코딩테스트 연습 - 6주차

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

programmers.co.kr

👨🏻‍💻 문제 풀이

복서 정렬하기는 각 선수의 몸무게와 경기 기록을 주었을 때

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

위의 조건을 적용하여 선수들을 정렬하는 문제입니다.

입력으로는 선수들의 몸무게가 선수 순서대로 들어있는 weights와

각 선수의 경기기록이 선수 순서대로 들어있는 head2head 리스트가 주어집니다.

 

여기서 제가 활용할 건 몸무게의 값과 경기기록이 "선수 순서대로" 들어있다는 것 입니다.

match_result_list = []

먼저 각 선수들의 정보를 (선수번호, 승률, 본인보다 무거운 선수를 이긴 횟수, 해당 선수의 몸무게) 의 형태로 저장할

리스트를 하나 선언해줍니다.

그 다음 경기기록 리스트에서 경기 기록을 하나씩 꺼내옵니다. 이때 enumerate를 활용하여 idx와 결과를 같이 꺼내줍니다.

for person_idx, results in enumerate(head2head):
        my_weight = weights[person_idx]
        win_num, win_goliath, match_num =0, 0, 0
        
        for result_idx, result in enumerate(results):

각 데이터의 값이 선수 순서대로 들어가 있으므로 enumerate 에서 나온 idx를 현재 선수의 순번으로 사용하고

이를 활용하여 몸무게 데이터에서도 현재 선수의 몸무게 값을 꺼내옵니다.

 

그리고 각 선수마다 정보를 만들 변수 값을 선언해줍니다.

경기기록에서 몇번 이겼는지를 체크할 win_num, 나보다 무거운 선수를 몇번이겼는지를 체크할 win_goliath

총 몇번의 경기를 했는지 체크할 match_num 이 값을 각각 0으로 설정합니다.

 

그 다음으로 각 경기기록에서 하나씩 값을 꺼내오는데 이때 각 경기기록의 순서도 선수순서대로 되어있으므로

여기서도 각각의 값에 접근할때 나오는 idx값을 활용해서 현재 경기기록에서 몇kg 몸무게의 선수와 겨뤘는지를 알수있게

weights에서 값을 꺼내옵니다.

if result != "N":
    match_num += 1

if result == "W":
    win_num += 1
    if weights[result_idx] > my_weight:
        win_goliath += 1

그럼 나온 값에서 N이 아닐경우 경기횟수(match_num)를 하나씩 늘려주고

W일 경우 경기에서 이긴횟수(win_num)을 하나씩 늘려주고 W이면서 weights에서 꺼내온 값 즉 현재 상대방의 몸무게가

내 몸무게보다 더 큰 경우 현재 선수보다 무거운 선수를 이긴 것이므로 win_goliath의 값을 하나 증가시켜줍니다.

win_percent = win_num / match_num * 100 if match_num != 0 else 0

이렇게 만들어진 값들 중 win_num과 match_num을 활용해서 승률을 구하는데 ( win_num / match_num * 100 )

모든 경기기록이 N일 경우가 존재하여 총 경기횟수(match_num)이 0 이 될 경우도 있으므로

0으로 나누어 오류가 나는 것을 방지하기 위해

if 조건문을 활용하여 match_num이 0일 경우는 그냥 0을 승률로 하도록 합니다.

match_result_list.append((person_idx + 1, win_percent, win_goliath, my_weight))

그리고 처음 말했던 것 처럼

각 선수들의 정보를 (선수번호, 승률, 본인보다 무거운 선수를 이긴 횟수, 해당 선수의 몸무게) 의 형태로 저장합니다.

match_result_list = sorted(match_result_list, key=lambda x: (-x[1], -x[2], -x[3], x[0]))

마지막으로 4가지 조건을 만족하도록 해당 조건을 sorted의 lambda조건에 넣어 정렬하고

answer = [result[0] for result in match_result_list]

각 값들의 맨 첫번째 값들만 남겨주면 끝! 입니다.

 

전체 코드는 아래를 참고해주세요.

👨🏻‍💻 코드 ( Solution )

def solution(weights, head2head):
    answer = []
    
    match_result_list = []
    
    for person_idx, results in enumerate(head2head):
        my_weight = weights[person_idx]
        win_num, win_goliath, match_num =0, 0, 0
        
        for result_idx, result in enumerate(results):
            if result != "N":
                match_num += 1

            if result == "W":
                win_num += 1
                if weights[result_idx] > my_weight:
                    win_goliath += 1
                    
        win_percent = win_num / match_num * 100 if match_num != 0 else 0            
                    
        match_result_list.append((person_idx + 1, win_percent, win_goliath, my_weight))
        
    match_result_list = sorted(match_result_list, key=lambda x: (-x[1], -x[2], -x[3], x[0]))
    
    answer = [result[0] for result in match_result_list]      
    
    return answer
 

GitHub - SOMJANG/CODINGTEST_PRACTICE: 1일 1문제 since 2020.02.07

1일 1문제 since 2020.02.07. Contribute to SOMJANG/CODINGTEST_PRACTICE development by creating an account on GitHub.

github.com

Comments