Weight for weight, CodeWars Kata
Weight for weight
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.
문제 설명이 재미를 위해 이것 저것 붙이다 보니 기네요. 우리는 숫자가 나열된 문자열을 받아 이것을 정해진 가중치로 정렬(Ascending)하여 출력해야 합니다.
룰은 다음과 같습니다.
- 숫자는 숫자를 이루는 하나하나의 개별 숫자의 합으로 가중치를 정합니다. 예를 들어
56
은5
와6
을 더한11
이 가중치가 됩니다. - 가중치가 같으면 일반적인
String
처럼 정렬합니다.180
과90
은 가중치가1
로 모두 동일합니다.String
은 알파벳 순서로 정렬하기 때문에 이 둘을 가중치로 정렬하면180, 90
순서로 출력됩니다.
인풋은 다음과 같습니다.
- 숫자가 나열된 문자열
My Solution
입력 문자열을 Stream
을 이용해 정렬처리한 후 문자열로 반환했습니다. 정렬에는 가중치를 적용하기 위해서 Custom Comparator를 사용했습니다.
가중치 계산을 위해 문자열을 공백문자열로 Split처리했습니다. (split("")
)
package com.codewars;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.Comparator;
public class WeightForWeight {
public static String orderWeight(String strng) {
return Arrays.stream(strng.split(" ")).sorted((String a, String b) -> {
int asum = Arrays.stream(a.split("")).mapToInt(Integer::parseInt).sum();
int bsum = Arrays.stream(b.split("")).mapToInt(Integer::parseInt).sum();
if (asum == bsum)
return a.compareTo(b);
else
return Integer.compare(asum, bsum);
}).collect(Collectors.joining(" "));
}
}
Best Practice
BP1
첫 번째 BP는 제 솔루션과 유사하지만 String.chars()
를 이용했습니다. String.chars()
를 이용하면 Split하지 않고 스트림을 바로 생성할 수 있네요. 기억해 두면 좋을 듯 합니다.
class BP {
public static String orderWeight(String string) {
String[] split = string.split(" ");
Arrays.sort(split, new Comparator<String>() {
public int compare(String a, String b) {
int aWeight = a.chars().map(c -> Character.getNumericValue(c)).sum();
int bWeight = b.chars().map(c -> Character.getNumericValue(c)).sum();
return aWeight - bWeight != 0 ? aWeight - bWeight : a.compareTo(b);
}
});
return String.join(" ", split);
}
}
BP2
두 번째 BP는 Comparator
의 thenComparing
메서드를 활용했습니다. sumDigits(String s)
를 미리 생성해두고 BP2::sumDigits
로 간결하게 비교한 것도 눈여겨 볼만 합니다. 여러 BP 중 가장 멋있는 코드인 것 같습니다.
class BP2 {
public static String orderWeight(String strng) {
return Arrays.stream(strng.split(" "))
.sorted(Comparator.comparing(BP2::sumDigits).thenComparing(String::compareTo))
.collect(Collectors.joining(" "));
}
private static Integer sumDigits(String s) {
return s.chars().map(c -> c - 48).sum();
}
}
'IT Contents > 프로그래밍 팁' 카테고리의 다른 글
What's a Perfect Power anyway?, CodeWars Kata 자바 솔루션 (0) | 2021.04.14 |
---|---|
Snail, CodeWars Kata 자바 솔루션 (0) | 2021.04.13 |
Tribonacci Sequence, CodeWars Kata 자바 솔루션 (0) | 2021.04.10 |
Counting Duplicates, CodeWars Kata 자바 솔루션 (0) | 2021.04.08 |
Convert string to camel case, CodeWars Kata 자바 솔루션 (0) | 2021.04.07 |
최근댓글