简体   繁体   中英

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.

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;
}

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

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)
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM