문제 설명
복서 선수들의 몸무게 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'입니다.
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 과 같은 방식으로 했다가 오답판정을 받았다. 이렇게 설정할 경우 승률이 낮으면 아래 조건을 확인하게 되버린다. 즉 승률이 같지만 않으면 해당 조건에서 끝나야한다. 그래서 위의 코드처럼 두 값이 같지 않으면 음 또는 양의 값을 내보내서 정렬되도록 하였다.
참고
'Problem Solving > Programmers' 카테고리의 다른 글
<Level 3> 단속 카메라 with JS (0) | 2021.09.02 |
---|---|
<Level 2> 게임 맵 최단거리 with JS (0) | 2021.09.01 |
<Level 2> 가장 큰 정사각형 찾기 with JS (1) | 2021.08.31 |
<Level 2> 큰 수 만들기 with JS (0) | 2021.08.27 |
<Level 2> H-index with JS (0) | 2021.08.25 |