Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive Sum of digits of number(until digit is less than 10) java 8 lambdas only

I am just practicing lamdas java 8. My problem is as follows

Sum all the digits in an integer until its less than 10(means single digit left) and checks if its 1

Sample Input 1

100

Sample Output 1

1 // true because its one

Sample Input 2

55

Sample Output 2

1     ie  5+5 = 10 then 1+0 = 1 so true

I wrote a code

System.out.println(Arrays.asList( String.valueOf(number).split("") ).stream()
                                                                    .map(Integer::valueOf)
                                                                    .mapToInt(i->i)
                                                                    .sum() == 1);

It works for the input 1 ie 100 but not for input 2 ie 55 which I clearly understand that in second case 10 is the output because the iteration is not recursive .

So how can I make this lambdas expression recursive so that it can work in second case also? I can create a method with that lambda expression and call it each time until return value is< 10 but I was thinking if there is any approach within lambdas.

Thanks

like image 709
singhakash Avatar asked Oct 25 '15 09:10

singhakash


2 Answers

If you want a pure lambda solution, you should forget about making it recursive, as there is absolutely no reason to implement an iterative process as a recursion:

Stream.iterate(String.valueOf(number),
               n -> String.valueOf(n.codePoints().map(Character::getNumericValue).sum()))
      .filter(s -> s.length()==1)
      .findFirst().ifPresent(System.out::println);

Demo

like image 131
Holger Avatar answered Sep 30 '22 17:09

Holger


Making lambdas recursive in Java is not easy because of the "variable may be uninitialized" error, but it can be done. Here is a link to an answer describing one way of doing it.

When applied to your task, this can be done as follows:

// This comes from the answer linked above
class Recursive<I> {
    public I func;
}

public static void main (String[] args) throws java.lang.Exception {
    Recursive<Function<Integer,Integer>> sumDigits = new Recursive<>();
    sumDigits.func = (Integer number) -> {
        int s = Arrays.asList( String.valueOf(number).split("") )
            .stream()
            .map(Integer::valueOf)
            .mapToInt(i->i)
            .sum();
        return s < 10 ? s : sumDigits.func.apply(s);
    };
    System.out.println(sumDigits.func.apply(100) == 1);
    System.out.println(sumDigits.func.apply(101) == 1);
    System.out.println(sumDigits.func.apply(55) == 1);
    System.out.println(sumDigits.func.apply(56) == 1);
}

I took your code, wrapped it in { ... }s, and added a recursive invocation on the return line.

Demo.

like image 38
Sergey Kalinichenko Avatar answered Sep 30 '22 16:09

Sergey Kalinichenko