Learn & Run

[Programmers] 복서 정렬하기 (Java, Kotlin) 본문

Algorithm/Programmers

[Programmers] 복서 정렬하기 (Java, Kotlin)

iron9462 2021. 9. 6. 23:32

https://programmers.co.kr/learn/courses/30/lessons/85002

 

코딩테스트 연습 - 6주차

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

programmers.co.kr

문제

복서 선수들의 몸무게가 weights, 복서 선수들의 전적을 나타내는 head2head가 인풋으로 주어집니다. 복서 선수들의 번호를 제시된 규칙에 맞게 반환하면 됩니다. 규칙은 아래와 같습니다.

 

1. 전체 승률이 높은 복서의 번호가 앞쪽으로 갑니다. 아직 다른 복서랑 붙어본 적이 없는 복서의 승률은 0%로 취급합니다.

2. 승률이 동일한 복서의 번호들 중에서는 자신보다 몸무게가 무거운 복서를 이긴 횟수가 많은 복서의 번호가 앞쪽으로 갑니다.

3. 자신보다 무거운 복서를 이긴 횟수까지 동일한 복서의 번호들 중에서는 자기 몸무게가 무거운 복서의 번호가 앞쪽으로 갑니다.

4. 자기 몸무게까지 동일한 복서의 번호들 중에서는 작은 번호가 앞쪽으로 갑니다.

 

접근 아이디어

1. 자료구조 Map을 이용하여 각 복서들의 순서와 무게를 저장합니다. 이후에 복서들간에 무게를 비교하여 정렬시 필요합니다.

2. 총 라운드 중에 이긴 라운드를 확인하여 승률을 구합니다. 1번에서 말한 것처럼 기준 복서가 다른 복서를 이겼을 때 몸무게가 덜나가는지 더나가는지 확인합니다.

3. 아래 코드중 list에 값을 저장하여 문제 규칙에 맞게 정렬한 후에 복서의 번호를 차례대로 반환합니다.

 

조심해야할 점

1. 아래 변수중에 승리나 패배시 카운팅하는 allRound의 변수가 0이 될 때 rate는 NaN값이 나오게 됩니다. 이에 대한 예외 처리를 꼭 해줘야합니다.

2. list에 저장된 값들에 대해서 순차적으로 정렬을 할 때 내림차순인지 오름차순인지 잘 확인하여야 합니다.

 

 

- Java

import java.util.*;

class Solution {
    
    public int[] solution(int[] weights, String[] head2head) {
        Map<Integer, Integer> map = new HashMap<>();

        //복서들의 순서와 무게 저장하기
        for(int i=0; i<weights.length ;i++) {
            map.put(i, weights[i]);
        }

        List<Boxer> list = new ArrayList<>();
        for(int i=0; i<weights.length; i++) {
            String result = head2head[i];

            int allRound = 0; //모든 라운드
            int winRound = 0; //이긴 라운드
            int bigRound = 0; //자신보다 무거운 복서를 이긴 라운드
            for(int j=0; j<result.length(); j++) {
                char ch = result.charAt(j);

                if(ch == 'N') continue;

                allRound++;
                if(ch == 'W') {
                    winRound++;
                    if(map.get(i) < map.get(j)) bigRound++;
                }
            }

            double rate = winRound / (allRound * 1.0d);
            if(allRound == 0) rate = 0;
            list.add(new Boxer(i + 1, weights[i], bigRound, rate));
        }

        list.sort((o1, o2) -> {
            if(o1.rate < o2.rate) return 1;
            else if(o1.rate == o2.rate) {
                if(o1.bigger < o2.bigger) return 1;
                else if(o1.bigger == o2.bigger) {
                    if(o1.weight < o2.weight) return 1;
                    else if(o1.weight == o2.weight) return o1.number - o2.number;
                    else return -1;
                }
                else return -1;
            }
            else return -1;
        });
        
        int[] answer = new int[list.size()];
        for(int i=0; i<list.size(); i++) {
            answer[i] = list.get(i).number;
        }

        return answer;
    }

    static class Boxer {
        int number;
        int weight;
        int bigger;
        double rate;
        Boxer(int number, int weight, int bigger, double rate) {
            this.number = number;
            this.weight = weight;
            this.bigger = bigger;
            this.rate = rate;
        }
    }
}

 

 

- Kotlin

import java.util.*;

class Solution {

    fun solution(weights: IntArray, head2head: Array<String>): IntArray {
        val map: MutableMap<Int, Int> = HashMap()

        //복서들의 순서와 무게 저장하기
        for (i in weights.indices) {
            map[i] = weights[i]
        }

        val list: MutableList<Boxer> = ArrayList<Boxer>()
        for (i in weights.indices) {
            val result = head2head[i]
            var allRound = 0 //모든 라운드
            var winRound = 0 //이긴 라운드
            var bigRound = 0 //자신보다 무거운 복서를 이긴 라운드
            for (j in 0 until result.length) {
                val ch = result[j]
                if (ch == 'N') continue
                allRound++
                if (ch == 'W') {
                    winRound++
                    if (map[i]!! < map[j]!!) bigRound++
                }
            }
            
            var rate = winRound / (allRound * 1.0)
            if (allRound == 0) rate = 0.0
            list.add(Boxer(i + 1, weights[i], bigRound, rate))
        }

        list.sortWith(Comparator { o1: Boxer, o2: Boxer ->
            if (o1.rate < o2.rate) 1
            else if (o1.rate == o2.rate) {
                if (o1.bigger < o2.bigger) 1
                else if (o1.bigger == o2.bigger) {
                    if (o1.weight < o2.weight) 1
                    else if (o1.weight == o2.weight)
                        o1.number - o2.number
                    else -1
                } else -1
            } else -1
        })

        return list.map { it.number }.toIntArray()
    }

    class Boxer(var number: Int, var weight: Int, var bigger: Int, var rate: Double)
}

 

좌(Java 채점 결과), 우(Kotlin 채점 결과)