CodeWars 코딩 문제 2021/01/28 - Weight for weight

이호현·2021년 1월 28일
0

Algorithm

목록 보기
69/138

[문제]

My friend John and I are members of the "Fat to Fit Club (FFC)". John is worried because each month a list with the weights of members is published and each month he is the last on the list which means he is the heaviest.

I am the one who establishes the list so I told him: "Don't worry any more, I will modify the order of the list". It was decided to attribute a "weight" to numbers. The weight of a number will be from now on the sum of its digits.

For example 99 will have "weight" 18, 100 will have "weight" 1 so in the list 100 will come before 99.

Given a string with the weights of FFC members in normal order can you give this string ordered by "weights" of these numbers?

Example:

"56 65 74 100 99 68 86 180 90" ordered by numbers weights becomes:

"100 180 90 56 65 74 68 86 99"

When two numbers have the same "weight", let us class them as if they were strings (alphabetical ordering) and not numbers:

180 is before 90 since, having the same "weight" (9), it comes before as a string.

All numbers in the list are positive numbers and the list can be empty.

Notes

  • it may happen that the input string have leading, trailing whitespaces and more than a unique whitespace between two consecutive numbers
  • For C: The result is freed.

(요약) 각 숫자들의 자리수를 다 더해서 오름차순 정렬. 합이 같으면 문자열 정렬.

[풀이]

function orderWeight(string) {
  const weights = string.split(' ');

  weights.sort((a, b) => {
    const num1 = a.split('').reduce((acc, num) => acc += (num * 1), 0);
    const num2 = b.split('').reduce((acc, num) => acc += (num * 1), 0);

    if(num1 < num2) {
      return -1;
    }
    else if(num1 === num2) {
      const length = a.length < b.length ? a.length : b.length;

      for(let i = 0; i < length; i++) {
        if(a[i] < b[i]) {
          return -1;
        }
        else if(a[i] > b[i]){
          return 1;
        }
      }

      if(a.length < b.length) {
        return -1;
      }
      else {
        return 1;
      }
    }
    else {
      return 1;
    }
  })

  return weights.join(' ');
}

우선 문자열을 공백을 기준으로 split()함.
그리고 정렬을 하는데 우선 각 자리수를 다 더한 값을 먼저 비교.
같으면 왼쪽부터 각 자리수 크기 비교.
위 과정에서 비교가 안되면 숫자 길이 비교.
저렇게 정렬된 배열을 마지막에 join()으로 합쳐서 return.

function orderWeight(string) {
  return string.split(' ').sort((a, b) => {
    const sumA = a.split('').reduce((acc, num) => acc += (num * 1), 0);
    const sumB = b.split('').reduce((acc, num) => acc += (num * 1), 0);

    if(sumA === sumB) {
      return a.localeCompare(b);
    }
    else {
      return sumA - sumB;
    }
  }).join(' ');
}

string 메소드중에 localeCompare가 있어서 사용해 보니까 코드길이가 확 줄었음...
리팩토링 하는 김에 배열 변수 따로 안 만들고 바로 return.

profile
평생 개발자로 살고싶습니다

0개의 댓글