Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Foreach loop with double condition in java8 using lambda

I have an exercise with this description:

1122 produces a sum of 3 (1 + 2) because the first digit (1) matches the second digit and the third digit (2) matches the fourth digit.
1111 produces 4 because each digit (all 1) matches the next.
1234 produces 0 because no digit matches the next.
91212129 produces 9 because the only digit that matches the next one is the last digit, 9.

I have written the following code:

String inputString = "1111"; // taking this number as example

int sum = 0;
for (int i = 0; i < inputString.length() - 1; i++) {
    if (inputString.charAt(i) == inputString.charAt(i + 1)) {
        sum += Integer.parseInt(String.valueOf(inputString.charAt(i)));
    }
    if (i + 2 == inputString.length() - 1) {
        if (inputString.charAt(i + 2) == inputString.charAt(0)) {
            sum += Integer.parseInt(String.valueOf(inputString.charAt(i + 2)));
        }
    }
}

The result of sum is 4, which is correct.

Now I'm trying to write the same one in Java8 using lambda but I can't figure out how to get the last condition inside my stream.

This is how far I got:

Integer sum = IntStream.range(0, (inputString.length() - 1)).boxed()
                .filter(j -> inputString.charAt(j) == inputString.charAt(j + 1))
                .mapToInt(i -> Integer.parseInt(String.valueOf(inputString.charAt(i)))).sum();
like image 642
Alex P. Avatar asked May 23 '26 21:05

Alex P.


2 Answers

The last condition is actually like the others if you consider the loop variable modulo the length: ((length-1) + 1) % length == 0

int length = inputString.length();

IntStream.range(0, length)
  .filter(i -> inputString.charAt(i) == inputString.charAt((i + 1) % length))
  .map(i -> Integer.parseInt(String.valueOf(inputString.charAt(i))))
  .sum();
like image 51
dfogni Avatar answered May 26 '26 09:05

dfogni


This is going to get really messy with streams as far as my knowledge goes, nevertheless, I enjoyed the challenge and here's how I'd do it:

First, create two functions:

  1. a mapper function from char to int to help reduce the code we're going to keep repeating.
  2. a predicate like function to validate whether two given characters are equal; again to help reduce the code we're going to keep repeating.

that is:

public static int mapper(String value, int index){
    return Integer.parseInt(String.valueOf(value.charAt(index)));
}

public static boolean areEqual(String inputString, int firstIndex, int secondIndex){
      return inputString.charAt(firstIndex) == inputString.charAt(secondIndex);
}

then you can accomplish the task by doing:

int sum = IntStream.range(0, inputString.length() - 1)
            .map(i -> areEqual(inputString, i, i + 1) &&
                    i + 2 == inputString.length() - 1 &&
                    areEqual(inputString, i + 2, 0)?
                    mapper(inputString, i) + mapper(inputString, i + 2) :
                    areEqual(inputString, i , i + 1) &&
                            i + 2 != inputString.length() - 1 ?
                            mapper(inputString, i) :
                            i + 2 == inputString.length() - 1 &&
                                    areEqual(inputString,i + 2, 0) &&
                                    inputString.charAt(i) != inputString.charAt(i + 1) ?
                                    mapper(inputString, i + 2) :
                                    inputString.charAt(i) == inputString.charAt(i + 1) ?
                                            mapper(inputString, i) : 0
            )
            .sum();

The solution above takes into consideration all the possible conditions that could be met hence the need to subsequently keep checking different conditions.

As an aside, another thing you might want to do to reduce the code more is by making inputString a global variable which you can then directly use within the two helper functions and thus meaning we can get rid of the inputString parameter both for methods.

like image 36
Ousmane D. Avatar answered May 26 '26 09:05

Ousmane D.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!