programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
• Campbell Ritchie
• Paul Clapham
• Ron McLeod
• Tim Cooke
• Junilu Lacar
Sheriffs:
• Rob Spoor
• Devaka Cooray
• Jeanne Boyarsky
Saloon Keepers:
• Jesse Silverman
• Stephan van Hulst
• Tim Moores
• Carey Brown
• Tim Holloway
Bartenders:
• Jj Roberts
• Al Hobbs
• Piet Souris

# Stream to sum up consecutive songs

Ranch Hand
Posts: 269
1
• 1
• Number of slices to send:
Optional 'thank-you' note:
Good Day All.

I'm on my way to solve a Pairs of Songs With Total Durations Divisible by 60 problem using streams.Though I've a solution using classic for loops, still curious how

can we get this done with stream API. Given an array which contains play duration of songs in minutes. User can select 2 songs and if sum of those 2 songs is multiple of 60 minutes then we count it as one

pair of songs available which is multiple of 60.

Test Data: [20, 40, 10, 25] = > Count = 0
[20+40] = 60%60 = 0 [One pair which is multiple of 60 minutes], Count = 1
[20+10] = 30 = > Not a multiple of 60, Count = 1
[20+25] = 45 = > Not a multiple of 60, Count = 1

I'm trying to acheive the same through stream, by summing the consecutive pairs in the array. Tried with reduce method and limit method to acheive the same functionality but I'm consuming more time and got stuck to proceed. Could someone shed some light on this to proceed or let me know what I should to learn in stream to get this done ?

Kind Regards.

author & internet detective
Posts: 40791
828
• Number of slices to send:
Optional 'thank-you' note:
That's a good question. This "solution" has two problems:
1) The inner stream would be more readable as a method
2) It gives the wrong answer because it doesn't generate unique pairs. That means 30/30 gets counted twice (instead of not at all) and 10/50, 10/50, 50/10, 50/10 get counted 4 times instead of 1

One would need a way to make the unique pairs. I can't think of an easy way to do it with streams. I'm curious if others can think of a way. I'm pretty sure this is a thought experiment as the original is pretty clear.

Mohammed Sardar.
Ranch Hand
Posts: 269
1
• Number of slices to send:
Optional 'thank-you' note:
Thank you so much Jenne for having a look at my help request.  Happy to say that  I came to know that streams can be nested this way but it was miserable I spent more hours to reach near the solution before I come here. Just sharing here I tried using the below array with above stream code to debug to learn additionally and got a mystic 3 in the place of 0 which is not expected !. int[] songsArr = new int[]{ 10, 15, 10}; From the result 3 I'm thinking whether the sum is happening at all. Can some one help me to understand ! Thanks again.

Bartender
Posts: 2899
150
• 1
• Number of slices to send:
Optional 'thank-you' note:

Jeanne Boyarsky wrote:... One would need a way to make the unique pairs. I can't think of an easy way to do it with streams. I'm curious if others can think of a way ...

My attempt :

I have eliminated duplicate count by using a set containing only the minimum of every pair.

Mohammed Sardar.
Ranch Hand
Posts: 269
1
• Number of slices to send:
Optional 'thank-you' note:
Thanks for the attempt Salvin. Practically, there're 3 pairs in this series [10,50], [30,30],[50,10] but we get it as 0. I couldn't debug stream code in IDE but is it due to the Set operation ?

Bartender
Posts: 4667
183
• Number of slices to send:
Optional 'thank-you' note:
Salvins method goes like this:

suppose the array is {0, 10, 50, 30, 40, 50, 30, 10}.
Then there are the pairs (10, 50), (50, 10), (30, 30) and (50, 10).
Then taking the minimum of each pair, we get: 10, 10, 30, 10.
Putting this in a Set, we keep the unique numbers 10 and 30, having a size of 2.

The logic of this is that we keep only those pairs for which the smaller element is unique among all the possible pairs. By doing so, you keep the pairs (10, 50) and (30, 30), two pairs. A simpler way to achieve this is to use '.distinct()'. For instance:

The method in your opening post has this direct translation:

If you allow pairs with, say, indices (1, 3) AND (3, 1), then you can have this:

NB: in Jeannes code snippet the last 'count()' should be a 'sum()'. Why?

But as you see: your nested for-loops are way easier.

salvin francis
Bartender
Posts: 2899
150
• 1
• Number of slices to send:
Optional 'thank-you' note:

Mohammed Sardar. wrote:...Practically, there're 3 pairs in this series [10,50], [30,30],[50,10]

I see only two. In my point of view, [10,50] is the same as [50,10] which is what my code logic of pairing/counting is based on.

Mohammed Sardar. wrote:but we get it as 0.

I am not clear about this. Were you able to run my code? It should print "pairCount" as 2 and not 0.

Mohammed Sardar. wrote:I couldn't debug stream code in IDE but is it due to the Set operation ?

If that is the case, then I suggest looking at methods like "peek()" that allows you to debug and print what's going on !! Let's see if you can work that out with any of the codes mentioned in this post.

Piet Souris wrote:A simpler way to achieve this is to use '.distinct()'.

Agreed, distinct is quite better than the set approach.

Mohammed Sardar.
Ranch Hand
Posts: 269
1
• 1
• Number of slices to send:
Optional 'thank-you' note:

Mohammed Sardar. wrote:but we get it as 0.

I am not clear about this. Were you able to run my code? It should print "pairCount" as 2 and not 0.

Yes, for one of the use case I got 0 in the place 2, but I missed that test data. For the above mentioned scenario, the result came well as expected.

Thanks a lot to all who shared their precious time and knowledge for this thread.