6

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

Tunaki
  • 132,869
  • 46
  • 340
  • 423
singhakash
  • 7,891
  • 6
  • 31
  • 65
  • 2
    Your whole operation can be simplified to `number.codePoints().map(Character::getNumericValue).sum()`, but you can’t make it recursive without creating a named method. – Holger Oct 25 '15 at 09:39
  • @Holger There are [ways](http://stackoverflow.com/q/19429667/335858) of making recursive lambdas without making a named method. They do require a named variable, though. – Sergey Kalinichenko Oct 25 '15 at 09:47
  • 1
    @dasblinkenlight: but using a named variable instead of a named method does not offer any advantage, but produces an additional stack frame in every recursive step, compared to ordinary recursion… – Holger Oct 25 '15 at 09:50
  • @Holger Absolutely! I am not saying it *should* be done, only that it *can* be done. – Sergey Kalinichenko Oct 25 '15 at 09:51
  • @Holger you mean `String.valueOf(number.codePoints().map(Character::getNumericValue).sum()` thanks for the help this would be my second question to shorten the code you made my day. – singhakash Oct 25 '15 at 09:54

2 Answers2

7

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

singhakash
  • 7,891
  • 6
  • 31
  • 65
Holger
  • 285,553
  • 42
  • 434
  • 765
3

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.

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 1
    Since the problem isn’t recursive, I added a much simpler solution. As far as I can see, most questions about making lambdas recursive are actually an XY problem. – Holger Oct 25 '15 at 10:03
  • @Holger I very much doubt that people are trying to solve actual problems with recursive lambdas. I think that most questions about recursive lambdas are driven by pure curiosity: programmers who are learning a new and exciting tool, are naturally trying to see how far they can push it. As it turns out, one can push it pretty far :-) – Sergey Kalinichenko Oct 25 '15 at 10:09
  • 1
    But these attempts lead into the wrong direction. People pushing things that far, tend to use the same unnecessarily complicated solutions in real life code. I’ve seen such code… – Holger Oct 25 '15 at 10:12