본문 바로가기

Problem Solving/Programmers

<Level 1> 복서 정렬하기 with JS

 

문제 설명

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

 

 

class Boxer {
  constructor(w, i) {
    this.weight = w;
    this.index = i;
    this.rate = 0;
    this.winHeavier = 0;
  }
  getRate(str) {
    let win = 0;
    let lose = 0;
    for (let c of str) {
      if (c == "W") win += 1;
      if (c == "L") lose += 1;
    }
    if (win + lose) {
      this.rate = win / (win + lose);
    }
  }
  getWinHeavier(weights, str) {
    for (let i = 0; i < str.length; i++) {
      if (str[i] === "W" && weights[i] > this.weight) {
        this.winHeavier += 1;
      }
    }
  }
}

 

 - 이 문제가 왜 레벨1에 있는지 모르겠다. 어쨌든 주어진 설명에 맞게 구현하기만 하면 돼서 그런것일까.

 

 - 정렬 시 필요한 정보들을 담기 위해 Boxer 라는 클래스를 만들어서 객체로 저장하도록 하였다.

 

function solution(weights, head2head) {
  const boxerArr = [];
  // 각 정보를 담은 boxer 배열 생성
  for (let i = 0; i < weights.length; i++) {
    const boxer = new Boxer(weights[i], i);
    boxer.getRate(head2head[i]);
    boxer.getWinHeavier(weights, head2head[i]);
    boxerArr.push(boxer);
  }
  // 정렬
  boxerArr.sort((a, b) => {
    if (a.rate !== b.rate) return b.rate - a.rate;
    if (a.winHeavier !== b.winHeavier) return b.winHeavier - a.winHeavier;
    if (a.weight !== b.weight) return b.weight - a.weight;
    return a.index - b.index;
  });

  return boxerArr.map((elem) => elem.index + 1);
}

 

 - 클래스 생성시 무게와 인덱스값을 넣었다. 무게를 넣음으로써 getWinHeavier 함수(자신보다 몸무게가 무거운 복서를 이긴횟수)에서 활용하였고, 정렬 시 세 번째 조건에서도 활용하였다. 

 

 - getRate 와 getWinHeavier 메소드를 실행하여 추가적으로 정보를 객체에 저장하고, boxerArr에 추가한다.

 

 - boxerArr을 조건에 맞게 순서대로 확인하며 정렬한다. 이 때, 처음에 (a.rate > b.rate) return -1 과 같은 방식으로 했다가 오답판정을 받았다. 이렇게 설정할 경우 승률이 낮으면 아래 조건을 확인하게 되버린다. 즉 승률이 같지만 않으면 해당 조건에서 끝나야한다. 그래서 위의 코드처럼 두 값이 같지 않으면 음 또는 양의 값을 내보내서 정렬되도록 하였다.

 

 


 

참고

 

 

코딩테스트 연습 - 6주차

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

programmers.co.kr