프로그래머스/level 1

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

binaryJournalist 2021. 9. 12. 21:38
반응형

 

 

출처: 프로그래머스 코딩 테스트 연습, https://programmers.co.kr/learn/challenges

 

 

 

 

 

 

sort 정렬 조건 때문에 매우 애먹음

 

 

** Javascript

 

 

문제 조건을 보면 아예 다 같은 경우는 있지 않아서 sort 메서드 내 return 0 은 제일 밑에 써주면 된다.

이것 때문에 계속 테스트 케이스가 한 문제씩 안 넘어가서 무려 일주일 동안 못 풀었다.

 

 

function solution(weights, head2head) {
    let arr = [];
    for (let i  = 0; i < weights.length; i++) {
        const stat = head2head[i].split("").reduce((acc, curr, index) => {
            acc[0] += (curr !== "N" && i !== index) ? 1 : 0; // 대결 총횟수
            acc[1] += (curr === "W") ? 1 : 0; // 이긴 횟수
            acc[2] += (weights[index] > weights[i] && curr === "W") ? 1 : 0; // 무거운 사람 이긴 횟수
            return acc;
        }, [0, 0, 0]);
        arr.push([ weights[i], ...stat, stat[1] / stat[0], i ]); // 무게, 대결 횟수, 이긴 횟수, 무거운 사람 이긴 횟수, 승률, 인덱스
    }
    arr.sort((a, b) => {
        if (a[4] > b[4]) return -1;
        if (a[4] < b[4]) return 1;
        if (a[3] > b[3]) return -1;
        if (a[3] < b[3]) return 1;
        if (a[0] > b[0]) return -1;
        if (a[0] < b[0]) return 1;
        if (a[5] < b[5]) return -1;
        if (a[5] > b[5]) return 1;
        return 0;
    });
    return arr.map((item) => item[5] + 1);
}

 

 

 

1등 추천 풀이는 아래와 같은데 sort 조건으로 || 가 들어가서 신기해서 가져와 봤다. true 인 값만 실행되므로 0은 아마 false 가 되어버리기 때문에 안 들어갈 것이다. 나열된 순서대로 조건을 맞춰보는 것으로 알고 있다.

 

 

function solution(weights, head2head) {
    return head2head.map((l, i) => l.split('').reduce((acc, v, j) => {
                acc[0] += v === 'W' ? 1 : 0;
                acc[1] += v === 'W' ? weights[i] < weights[j] ? 1 : 0 : 0;
                acc[2] += v === 'L' ? 1 : 0
                return acc;
            }, [0, 0, 0])
            )
            .map((v) => [v[0] / (v[0] + v[2]), v[1]])
            .map((v, i) => [i + 1, {t: v[0], s: v[1], w : weights[i]}])
            .sort((a, b) => b[1].t - a[1].t || b[1].s - a[1].s || b[1].w - a[1].w || a[0] - b[0])
            .map((v) => v[0]);
}

 

 

1등 풀이를 참고해서 내 풀이를 고치면

 

function solution(weights, head2head) {
    let arr = [];
    for (let i  = 0; i < weights.length; i++) {
        const stat = head2head[i].split("").reduce((acc, curr, index) => {
            acc[0] += (curr !== "N" && i !== index) ? 1 : 0; // 대결 총횟수
            acc[1] += (curr === "W") ? 1 : 0; // 이긴 횟수
            acc[2] += (weights[index] > weights[i] && curr === "W") ? 1 : 0; // 무거운 사람 이긴 횟수
            return acc;
        }, [0, 0, 0]);
        arr.push([ weights[i], ...stat, stat[1] / stat[0], i ]); // 무게, 대결 횟수, 이긴 횟수, 무거운 사람 이긴 횟수, 승률, 인덱스
    }
    arr.sort((a, b) => b[4] - a[4] || b[3] - a[3] || b[0] - a[0] || a[5] - b[5]);
    return arr.map((item) => item[5] + 1);
}

 

이렇게 된다.

 

 

 

** Java

 

import java.util.*;

class Solution {
    public int[] solution(int[] weights, String[] head2head) {
        int[][] arr = new int[weights.length][6];
        for (int i = 0; i < weights.length; i++) {
            arr[i][0] = weights[i]; // 무게
            arr[i][5] = i; // 인덱스
            for (int j = 0; j < head2head[i].length(); j++) {
                char nwl = head2head[i].charAt(j);
                arr[i][1] += (nwl != "N".charAt(0) && i != j) ? 1 : 0; // 총 횟수
                arr[i][2] += ("W".charAt(0) == nwl) ? 1 : 0; // 이긴 횟수
                arr[i][3] += (weights[j] > weights[i] && nwl == "W".charAt(0)) ? 1 : 0; // 더 무거운 사람 이긴 횟수
            }
            arr[i][4] = (arr[i][1] == 0) ? 0 : (int)((double)arr[i][2] / arr[i][1] * 10000000);
        }
        Arrays.sort(arr, (a, b) -> {
            if (a[4] != b[4]) return b[4] - a[4];
            if (a[3] != b[3]) return b[3] - a[3];
            if (a[0] != b[0]) return b[0] - a[0];
            return a[5] - b[5];
        });
        int[] answer = new int[weights.length];
        for(int i = 0; i < weights.length; i++) {
            answer[i] = arr[i][5] + 1;
        }
        return answer;
    }
}

 

 

승률 부분도 int 로 받아서 난감해했는데 결국 매우 큰 수를 곱하였다.

 

 

 

** Python

 

 

from functools import cmp_to_key

def sortBoxer(a, b):
    if a[4] != b[4]: return b[4] - a[4]
    if a[3] != b[3]: return b[3] - a[3]
    if a[0] != b[0]: return b[0] - a[0]
    return a[5] -b[5]

def solution(weights, head2head):
    answer = []
    for i in range(len(weights)):
        answer.append([0, 0, 0, 0, 0, 0])
    for i in range(len(weights)):
        answer[i][0] = weights[i]
        answer[i][5] = i
        for j in range(len(head2head[i])):
            answer[i][1] += 1 if head2head[i][j] != "N" and i != j else 0
            answer[i][2] += 1 if head2head[i][j] == "W" else 0
            answer[i][3] += 1 if weights[j] > weights[i] and head2head[i][j] == "W" else 0
        answer[i][4] = 0 if answer[i][1] == 0 else answer[i][2] / answer[i][1]
    return list(map(lambda i: i[5] + 1 , sorted(answer, key = cmp_to_key(sortBoxer))))

 

 

이번주 일등 파이썬 코드...파이썬 천재

 

def solution(weights, head2head):
    result = []
    l = len(weights)
    # 한 번에 정렬해서 풀어봅시다!
    ans = [[0 for _ in range(4)] for _ in range(l)] # 승률, 무거운복서 이긴횟수, 자기 몸무게, 번호(음수로)
    for i in range(l):
        ans[i][2] = weights[i]
        ans[i][3] = -(i+1)
        cnt = 0 # 판수
        for j in range(l):
            if head2head[i][j] == 'W':
                ans[i][0] += 1 # 일단 이김
                cnt += 1
                if weights[i] < weights[j]:
                    ans[i][1] += 1 # 무거운 복서 이김
            elif head2head[i][j] == 'L':
                cnt += 1 # 판수만 늘려준다
        if cnt == 0:
            ans[i][0] = 0
        else:
            ans[i][0] /= cnt
    ans.sort(reverse=True) # 역순으로 정렬하면 모든 조건이 한 번에 정렬된다

    for i in range(l):
        result.append(-ans[i][3])
    return result

 

 

인덱스를 음수로 하는 건 진짜 대박이었다.

반응형