Integers: Recreation One, CodeWars Kata
Integers: Recreation One
1, 246, 2, 123, 3, 82, 6, 41
are the divisors of number 246
. Squaring these divisors we get: 1, 60516, 4, 15129, 9, 6724, 36, 1681
. The sum of these squares is 84100
which is 290 * 290
.
Task
Find all integers between m
and n
(m and n integers such as 1 <= m <= n) such that the sum of their squared divisors is itself a square.
We will return an array of subarrays or of tuples (in C an array of Pair) or a string. The subarrays (or tuples or Pairs) will have two elements: first the number the squared divisors of which is a square and then the sum of the squared divisors.
Example:
list_squared(1, 250) --> [[1, 1], [42, 2500], [246, 84100]]
list_squared(42, 250) --> [[42, 2500], [246, 84100]]
The form of the examples may change according to the language, see "Sample Tests".
Note
In Fortran - as in any other language - the returned string is not permitted to contain any redundant trailing whitespace: you can use dynamically allocated character strings.
문제 해석
주어지는 입력값 m, n
사이의 수 중에서 약수의 제곱의 합이 어떤 수의 거듭제곱인 수를 모두 찾는 문제입니다. 예제의 246
은 약수의 거듭제곱의 합이 84100
이고 이것은 290*290
입니다. 우리는 이런 수들을 모두 찾아서 해당하는 숫자와 거듭제곱의 합을 쌍으로 리턴해주어야 합니다.
입력값
long m, n
: 숫자를 찾을 범위
출력값
String result
: [[숫자, 거듭제곱의 합]...] 형태로 결과를 출력
My Solution
m
부터 n
까지 루프를 돌면서 약수를 찾아 ArrayList
에 담았습니다. 그리고 Stream
을 이용해서 먼저 map(item -> item * item)
거듭제곱을 하고, reduce((a, b) -> a + b)
로 거듭제곱의 합을 구했습니다. 그다음 Math.sqrt()를 이용해서 거듭제곱인지 확인했습니다. 결과 출력은 Arrays.deepToString()
을 활용했습니다.
package com.codewars;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.LongStream;
public class IntegersRecreationOne {
public static String listSquared(long m, long n) {
ArrayList<Long[]> listSquare = new ArrayList<Long[]>();
for (long N = m; N <= n; N++) {
ArrayList<Long> list = new ArrayList<Long>();
for (long div = 1; div <= N; div++) {
if (N % div == 0) {
if (!list.contains(div))
list.add(div);
}
}
if (!list.isEmpty()) {
long multi = list.stream().map(item -> item * item).reduce((a, b) -> a + b).get();
if ((long) Math.sqrt(multi) * (long) Math.sqrt(multi) == multi) {
listSquare.add(new Long[] { N, multi });
}
}
}
return Arrays.deepToString(listSquare.toArray());
}
}
Best Practice
BP1
Math.sqrt()
API를 적극 활용한 답안입니다. 결과를 String으로 조립해 나가는 게 흥미롭네요.
class SumSquaredDivisorsBP {
public static String listSquared(long m, long n) {
// your code
String result = "[";
for (long i = m; i <= n; i++) {
if (Math.round(Math.sqrt(sumOfSquareDivisors(i))) == Math.sqrt(sumOfSquareDivisors(i))) {
result += "[" + i + ", " + sumOfSquareDivisors(i) + "], ";
}
}
return result.length() > 1 ? result.substring(0, result.length() - 2) + "]" : "[]";
}
public static long sumOfSquareDivisors(long n) {
return LongStream.range(1, n + 1).filter(i -> n % i == 0).map(i -> i * i).sum();
}
}
BP2
루프를 사용하는 대신 LongStream
을 활용한 게 눈여겨 볼만합니다.
class SumSquaredDivisorsBP2 {
public static String listSquared(long m, long n) {
ArrayList<String> strings = new ArrayList<>();
LongStream.rangeClosed(m, n).forEach(current -> {
long sum = LongStream.rangeClosed(1, current).filter(i -> current % i == 0).map(i -> i * i).sum();
if (Math.sqrt(sum) % 1 == 0)
strings.add(String.format("[%d, %d]", current, sum));
});
return String.valueOf(strings);
}
}
'IT Contents > 프로그래밍 팁' 카테고리의 다른 글
Sum by Factors, CodeWars Kata 자바 솔루션 (0) | 2021.04.17 |
---|---|
Strip Comments, CodeWars Kata 자바 솔루션 (0) | 2021.04.16 |
What's a Perfect Power anyway?, CodeWars Kata 자바 솔루션 (0) | 2021.04.14 |
Snail, CodeWars Kata 자바 솔루션 (0) | 2021.04.13 |
Weight for weight, CodeWars Kata 자바 솔루션 (0) | 2021.04.12 |
최근댓글