복서

은유로그·2021년 9월 30일
0

👩‍💻 algorithm

목록 보기
2/11

🔨 오늘의 문제 : 복서

📝 문제 설명은 여기서 확인 가능하다.
✅ 코드 실행 - 3개 중 3개 통과! (๑˙ᴗ˙๑)
❌ 제출 후 채점하기 - 12개 중 1개 통과.. ( ᴗ_ᴗ̩̩ )


입출력 예시 ( 입력 : weights, head2head / 출력 : result )

  • weights = [50,82,75,120]
  • head2head = ["NLWL","WNLL","LWNW","WWLN"]
  • result = [3,4,1,2]

  • weights = [145,92,86]
  • head2head = ["NLW","WNL","LWN"]
  • result = [2,3,1]

  • weights = [60,70,60]
  • head2head = ["NNN","NNN","NNN"]
  • result = [2,1,3]

💬 생각한 수도코드

  • 입력받은 weights와 head2head를 통해 아래와 같은 객체로 이루어진 배열(info)을 만든다.
  • [{ 선수 번호: n, 승률: n, 자기보다 무거운 복서를 이긴 횟수: n, 몸무게: n }, ...]
  • 선수 번호 : i + 1
  • 승률 : ((100 / 경기 횟수) * 이긴 횟수)의 소수점 둘째자리까지 표시 / 단, 다른 복서랑 붙어본 적이 없는 복서의 승률 = 0
  • 자기보다 무거운 복서를 이긴 횟수 : head2head[i]에서 W의 인덱스 + 1 선수 번호의 몸무게와 본인 몸무게와 비교해서 본인 몸무게가 작으면 +1 크면 아무 변화 없음
  • 몸무게 : weights[i]
  • info의 길이만큼 반복한다.
  • result에 담는 순서 (앞으로 오는 순서)는
  1. 승률이 높고,
  2. 승률이 같다면 자기보다 무거운 복서를 이긴 횟수가 많고,
  3. 자기보다 무거운 복서를 이긴 횟수가 같다면 몸무게가 무겁고,
  4. 몸무게가 같다면 선수 번호가 빠른 순서

👩‍💻 코드

function solution(weights, head2head) {
  // 원하는 정보 담아 줄 배열 만들기
    let info = new Array(weights.length);
    let result = new Array;
  
  // 자기보다 무거운 복서를 이긴 횟수 구하는 함수
  // 입력 : head2head[i]와 i / 출력 : cnt
    const win = (str, num) => {
        let cnt = 0;
      // 입력받은 str에서 'W'를 찾고, 본인 몸무게와 이긴 상대 몸무게를 비교해 상대 몸무게가 크다면 cnt++
        for(let i = 0; i < str.length; i++){
            if(str[i] === 'W' && weights[i] > weights[num]) cnt++;
        }
        return cnt;
    }
    
    for(let i = 0; i < info.length; i++){
        info[i] = {
          // 선수 번호
            player: i + 1,
          // 승률 : ((100 / 경기 횟수) * 이긴 횟수)의 소수점 둘째자리까지 표시
            winningrate: Number(((100 / (weights.length - 1)) * (head2head[i].match(/W/g) || []).length).toFixed(2)),
          // 자신보다 무거운 선수를 이긴 횟수 -> 위에 구현한 함수로 표현
            winning: win(head2head[i], i),
          // 몸무게
            weight: weights[i]
        }
    }
    
  // result의 담는 순서 1번째에 따라 winningrate에 따라 정렬
    result = info.sort((a, b) => b.winningrate - a.winningrate);
    
  // 2, 3, 4번째에 따라 result 정렬
    for(let i = 0; i < result.length - 1; i++){
        let tmp;
      
      // 2번째 경우 : 1번째 경우가 같다면, 자신보다 무거운 선수를 이긴 횟수 확인
        if(result[i].winningrate === result[i + 1].winningrate && result[i].winning < result[i + 1].winning){
            tmp = result[i];
            result[i] = result[i + 1];
            result[i + 1] = tmp;
        }
      
      // 3번째 경우 : 2번째 경우가 같다면, 몸무게가 무거운지 확인
        if(result[i].winningrate === result[i + 1].winningrate && result[i].winning === result[i + 1].winning && result[i].weight < result[i + 1].weight){
            tmp = result[i];
            result[i] = result[i + 1];
            result[i + 1] = tmp;
        }
      
      // 4번째 경우 : 3번째 경우가 같다면, 선수 번호가 작은지 확인
        if(result[i].winningrate === result[i + 1].winningrate && result[i].winning === result[i + 1].winning && result[i].weight === result[i + 1].weight && result[i].player > result[i + 1].player){
            tmp = result[i];
            result[i] = result[i + 1];
            result[i + 1] = tmp;
        }
    }
    
  // 원하는 출력을 위해 result에 선수 번호로 재할당하기
    for(let i = 0; i < result.length; i++){
        result[i] = result[i].player;
    }
    
  // 출력
    return result;
}

❗️ 체크할 점

승률 구하는 부분의 수도코드

((100 / 경기 횟수) * 이긴 횟수)의 소수점 둘째자리까지 표시

코드

Number(((100 / (weights.length - 1)) * (head2head[i].match(/W/g) || []).length).toFixed(2))

경기 횟수는 본인은 본인과 경기할 수 없으니 전체 선수(weights의 길이) - 1이라 생각했다.
-> weights.length - 1

이긴 횟수는 본인 경기 이력에서 'W'를 찾아야된다고 생각해서 정규표현식으로 구했다.
-> head2head[i].match(/W/g) || []).length
-> || [] 해준 이유는, 'W'가 없을 수도 있기 때문에 'W'이 없다면 빈 배열을 줘서 길이가 0이되게 함(길이가 0이면 횟수도 0)

소수점 둘째자리 표현은 toFixed(n)를 생각했는데, 그러면 string 타입으로 표현되기 때문에 전체적으로 Number를 감싸줬다.
-> Number(숫자.toFixed(2))


🤔 느낀점

열심히 풀었는데 제출 후 채점하기에서 똥망해버려서 매우 아쉽다 🥲 아무래도 마지막에 경우에 따라 result 재정렬하는 부분이 문제일 거라고 추측되는데 오늘은 더이상 고치고싶지가않아 😫...
그리고 애초에 info를 재정렬하고 result에는 info 각 요소의 player 값만 담으면 되지않을까? winning의 값을 구할 때는 function win을 통해 구했는데, 말고 다른 방법은 도저히 생각이 안났다. 한 번에 구할 수 있음 좋겠지만 나의 능력밖.. •́︿•̀ 。 이래저래 적어보니 아쉬운 투성이다.. 😂

다시 생각해볼 부분을 정리하자면
1. info를 정의한 후, result가 아닌 info를 조건에 맞게 정렬하자.
2. 정렬하는 코드는 다시 생각해보자. (지금 너무 복잡함 ㅜㅜ)
3. result에는 바로 정렬된 info 각 요소의 player 값을 할당하자.
4. 위 항목들이 전부 된다면! 여유롭다면! info 정의할 때, function win을 통해서가 아니라 반복문 안에서 정의될 수 있도록 생각해보자.

profile
๑•‿•๑

0개의 댓글