doublemc
doublemc

Reputation: 3301

Calculate sum of the digits to the consecutive power in given number

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

Answers (4)

smac89
smac89

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

Andreas
Andreas

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

Maciej Stępyra
Maciej Stępyra

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());

```

  1. generate power values
  2. extract digit from char at given position
  3. calculate power of extracted number
  4. summarize everything

Upvotes: 2

Andrew Jenkins
Andrew Jenkins

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

Related Questions