Reputation: 3301
What is the best way to calculate sum of the digits to the consecutive power in a method?
Examples:
calculateSum(5) -> returns 5^1 = 5
12 -> 1^1 + 2^2 = 5
26 -> 2^1 + 6^2 = 38
122 -> 1^1 + 2^2 + 2^3 = 13
I wanted to use stream because I'm trying to practice some J8 functionalities but couldn't find a way to make it work.
EDIT: I need it to solve this kata: https://www.codewars.com/kata/5626b561280a42ecc50000d1/train/java
EDIT2: Here is my code so far:
public static void calculateSum(int input) {
String[] number = String.valueOf(input).split("");
Map<Integer, Integer> map = Arrays.stream(number)
.map(Integer::valueOf)
.map(d -> (int) Math.pow(d, list.indexOf(d)))
.collect(Collectors.toMap(d));
}
I don't know how to map digits from number array
with their consecutive powers so then I can just sum values from that map.
Upvotes: 0
Views: 3914
Reputation: 43068
To fix what you already had, the trick is to use IntStream
public static void calculateSum(int input) {
String[] number = String.valueOf(input).split("");
int sum = IntStream.range(0, number.length)
.map(i -> (int)Math.pow(Integer.valueOf(number[i]), i + 1))
.sum();
System.out.println(sum)
}
Upvotes: 2
Reputation: 159086
FYI: Stream is not a good solution to this kind of problem. Forcing the use of Streams is bad coding. Part of writing good code, is to recognize the correct tool for the job, and Stream is not the tool to use here.
To prevent any potential issues with inaccuracy of double
, here is a pure-int
solution:
private static int calculateSum(int input) {
if (input < 0)
throw new IllegalArgumentException("Negative: " + input);
int[] digit = new int[10], power = new int[10];
for (int i = 0, n = input; n != 0; i++, n /= 10) {
for (int j = 0; j < i; j++)
power[j] *= digit[j];
power[i] = digit[i] = n % 10;
}
int sum = 0;
for (int i = 0; i < 10; i++)
sum += power[i];
if (sum < 0)
throw new ArithmeticException("Overflow: " + input);
return sum;
}
Test
public static void main(String[] args) {
test(5);
test(12);
test(26);
test(122);
test(Integer.MAX_VALUE);
test(1999999998);
}
private static void test(int input) {
System.out.printf("%d -> %d%n", input, calculateSum(input));
}
Output
5 -> 5
12 -> 5
26 -> 38
122 -> 13
2147483647 -> 284684832
1999999998 -> 1509589865
Note that a 10-digit number ending in 9
will overflow.
Upvotes: 1
Reputation: 320
This should work for You:
```
String str = String.valueOf(122);
DoubleSummaryStatistics collect = IntStream.range(0, str.length()) //1
.mapToObj(i -> {
int digit = Character.digit(str.charAt(i), 10); //2
return Math.pow(digit, i + 1); //3
})
.collect(Collectors.summarizingDouble(i -> i)); //4
System.out.println(collect.getSum());
```
Upvotes: 2
Reputation: 1609
Here's a solution without streams.
public static int digitPow(int n) {
int result = 0;
int count = (int)(Math.log10(n) + 1); // number of digits in n
while (count > 0) {
result += Math.pow((n % 10), count);
n /= 10;
count--;
}
return result;
}
Upvotes: 5