• Post Reply Bookmark Topic Watch Topic
  • New Topic
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
  • Devaka Cooray
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Jeanne Boyarsky
  • Tim Cooke
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Tim Moores
  • Mikalai Zaikin
  • Carey Brown
Bartenders:

what is wrong with this Stream function ?

 
Ranch Hand
Posts: 1013
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi guys,

I am lost on Java 8 Streams and it does not get easier with the way the question was asked in this exercise at

https://exercism.org/tracks/java/exercises/sum-of-multiples/edit




//Given a number, find the sum of all the unique multiples of particular numbers up to
//but not including that number.
//
//If we list all the natural numbers below 20 that are multiples of 3 or 5,
//we get 3, 5, 6, 9, 10, 12, 15, and 18.
//
//The sum of these multiples is 78.





I hope someone could pinpoint the mistakes. Tks.
 
Saloon Keeper
Posts: 10551
83
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Looks like set is never filled with anything so is all zeros.

What is the problem you are seeing?
 
Marshal
Posts: 78659
374
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

tangara goh wrote:. . .

That line is imprecise; you certainly don't want nulls, but please use a different exception (NullPointerException) and a more accurate error message. Yes, you do have to be very precise when writing code. I can't see an empty set being a problem; you will simply get an empty OptionalInt and you can use orElse(0). And I can't see why negative numbers would be a problem.
I would be wary of any site where they think set is a good name for an array.
I think you should go through the different methods of the IntStream interface. Start by writing down how you would add all the numbers in an array. Then work out how to remove duplicates or numbers greater than your limit.

. . . . Tks.

Please avoid abbreviations; I have seen Google translate struggle with “Tks”.
Also, use spaces for indenting rather than tabs, and please find out how to shorten long lines like line 11 there.
 
tangara goh
Ranch Hand
Posts: 1013
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Carey Brown wrote:Looks like set is never filled with anything so is all zeros.

What is the problem you are seeing?



The problem is that it is returning zero since set is not returning anything.

How do i render it in the main void method ?
 
Bartender
Posts: 5462
212
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi Tangara,

there is no need to have an int[] parameter. Read the exercise again. So you woulg get something like
 
tangara goh
Ranch Hand
Posts: 1013
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Piet Souris wrote:hi Tangara,

there is no need to have an int[] parameter. Read the exercise again. So you woulg get something like



That is what i thought, too.

But, in that platform, they have put int[]set as the parameters.

Hence, I am stumped and my heart filled with horror that I can't do anything with that int[]set inside as a parameter....

And there is no way to test out since that set is used to contain the unique number of mulitples.  Either I pre-generated it then i do that getSum using this pre-generated, doing 2 separate methods but then this is not given in the platform and all is given is that getSum method so I'm not sure if it should be done this way or wat ?

 
Campbell Ritchie
Marshal
Posts: 78659
374
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That won't return an int, Piet.
I missed the bit about dividing by 3 and 5. In which case, as you say, you don't need an array. You can use the method to create a stream of increasing numbers.
 
Piet Souris
Bartender
Posts: 5462
212
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Doesn't return an int? Admitted, I wrote it out of my head, but...

@Tangara
I don't see a method signature on the page you linked to, can you show us where you got that signature from?
 
tangara goh
Ranch Hand
Posts: 1013
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Piet Souris wrote:hi Tangara,

there is no need to have an int[] parameter. Read the exercise again. So you woulg get something like



why did you %3 and %5 when it should be i % number to get the multiples and then to use the set to filter the unique ones ?
 
Piet Souris
Bartender
Posts: 5462
212
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As I said, I could not find a method signature, and so I used 3 and 5 as in the example given.

But assuming the array is an array of possible divisors, in my example {3, 5}, you could have a helper method like:

and so you could have this method
 
Campbell Ritchie
Marshal
Posts: 78659
374
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

tangara goh wrote:. . . then to use the set . . .

What set? You haven't got a set anywhere. You only appear to have an array.
 
tangara goh
Ranch Hand
Posts: 1013
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Piet Souris wrote:As I said, I could not find a method signature, and so I used 3 and 5 as in the example given.

But assuming the array is an array of possible divisors, in my example {3, 5}, you could have a helper method like:

and so you could have this method



Sorry Piet, my bad... there is no parameter in the getSum() method at all.

It is my first time dealing with DSA combined with OOP so I am confused by that constructor what it is for.

But, really I don't understand why bind the set and the num at class level to the algorithm ?

 
Marshal
Posts: 8829
631
Mac OS X VI Editor BSD Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@OP

So you just need to incorporate into the template you have been given a code Piet wrote.

What is DSA?


i.e.

Or


Think which approach is better and why.
 
Campbell Ritchie
Marshal
Posts: 78659
374
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
. . . and tell us why line 8 in Liutauras' second code block might cause problems.
 
tangara goh
Ranch Hand
Posts: 1013
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Liutauras Vilda wrote:@OP

So you just need to incorporate into the template you have been given a code Piet wrote.

What is DSA?


i.e.

Or


Think which approach is better and why.



If I were to use the first method, then what do i do in the main void method ?



cos I can't create a new int[number] and it is weird to make set static in order to bring it in....and it can't be static since the number length will change ?

 
Carey Brown
Saloon Keeper
Posts: 10551
83
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

 
tangara goh
Ranch Hand
Posts: 1013
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Carey Brown wrote:



I am sorry but I still don't see why the class is designed this way because we have to put in the new int[] {3,5} where actually this is not told to us, and then we have to pre-calculated the set array which is the number multiples ?

Maybe i am stupid, i still can't grasped why it is designed this way
 
Piet Souris
Bartender
Posts: 5462
212
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi Tangara,

It is just one way to do it. What happens is that they create an instance of your class via the two-parameter constructor, and then call the getSum-metod on that instance. Since that method has no parameters, you have to make fields of the constructor-parameters, that you use in getSum.

You do not need a main-method. I just ran it, and got an error because my IntStream was unknown, so either you also must do the import, or you do not use an IntStream.
 
Campbell Ritchie
Marshal
Posts: 78659
374
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think I would have used int... instead of int[], throughout, because that affords more flexibility in supplying arguments.
The reason the class was designed that way is so you can make it an object. That object encapsulates both data (the array, multiplier, and result) and behaviour (producing the result). It is possible to copy the array as a field, but that introduces potential pitfalls, which disappear if you use the array immediately. But maybe only in a singly‑threaded program.
Piet's problem about imports can be explained simply by saying it is included in or implied by the //... in line 16.
 
Campbell Ritchie
Marshal
Posts: 78659
374
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The method in lines 14‑17 is running as a pure function; it might beneficially have been made private static.
 
Campbell Ritchie
Marshal
Posts: 78659
374
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What I said in my last post suggests you can use that method in a functional style. But the example you showed in your first post has modifiers inconsistent with that. I don't like over‑specification like that, and my liking for that website you found has not increased.
 
tangara goh
Ranch Hand
Posts: 1013
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:What I said in my last post suggests you can use that method in a functional style. But the example you showed in your first post has modifiers inconsistent with that. I don't like over‑specification like that, and my liking for that website you found has not increased.



Hmm...I thought that I was lucky to chance upon that site where they mixed OOP with DSA for a more complete educations.

What other sites are out there like codewar is free but with added OOP to the exercises ?
 
Sheriff
Posts: 17626
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The parameter int[] set is misleadingly named. It is actually the set of factors that you need to get multiples of.

You could have figured this out by looking at the test code:

So the candidate numbers you need to sum are:

multiples of 5 that are less than 51:
5, 10, 15, 20, 25, 30, 35, 40, 45, 50

multiples of 25 that are less than 51:
25, 50

Since 25 and 50 are common to both sets of multiples, you only add them to the answer once. So basically, for this particular test, the answer would be the sum of all multiples of 5 that are less than 51 which is 275.
 
Junilu Lacar
Sheriff
Posts: 17626
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
One algorithm for a solution would be:
1. Iterate over the set of factors given (the second parameter, int[] set)
1a. For each factor, generate all the multiples of that factor that are less than the given number (the first parameter)
1b. Collect all the multiples generated in 1a, taking only unique values

2. Sum all the numbers collected in 1b.
 
Campbell Ritchie
Marshal
Posts: 78659
374
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

tangara goh wrote:. . . I thought that I was lucky to chance upon that site . . .

Afraid I think you were rather unlucky. Don't know of any sites teaching OOP; sorry. Maybe somebody else will know.
 
Junilu Lacar
Sheriff
Posts: 17626
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This passes all tests:

Maybe there's a shorter/better way to do it... ?
 
Junilu Lacar
Sheriff
Posts: 17626
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

tangara goh wrote:I hope someone could pinpoint the mistakes. Tks.


Your code fails two tests, both with a division by zero exception.


 
Campbell Ritchie
Marshal
Posts: 78659
374
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Let's try multiplying all numbers up to a limit, by a multiplier, and excluding numbers divisible by two factors.
  • Line 1: Declares the result. Creates an IntStream iterating 0...limitexclusive. If limit < 1 we get sum = 0. If limit = 20 we get 20 numbers, the largest being 19.
  • Line 2: Creates a second IntStream by filtering in (retaining) numbers not dividing exactly by factor1 and by factor2. If either factor is 0, the division will throw an exception. If either factor has an absolute value greater than or equal to limit, that test with % will never produce 0.
  • Line 3: Produces a third IntStream whose elements are those of its predecessor multiplied by something. There is a risk of arithmetic overflow here or in the next stage if the numbers are large enough.
  • Line 4: Collects the sum as an OptionalInt.
  • Line 5: If any Stream was empty, you will have an empty OptionalInt, in which case you can convert that to 0 with its  orElse() method.
  •  
    Junilu Lacar
    Sheriff
    Posts: 17626
    300
    Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    This way also passes all 16 tests:

    Note that the filter to guard against division by zero is needed because there are test cases that include 0 in the second parameter.

    The first approach I shared generated all the multiples of the numbers given in the array of factors (that's what they're referred to in the problem and tests).

    This second approach checks if a number is a multiple of any of the factors.

    Either way works. Which one saves you a few cycles depends on the values that are passed in. I haven't spent any time analyzing the performance of each algorithm though.
     
    Carey Brown
    Saloon Keeper
    Posts: 10551
    83
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
     
    Junilu Lacar
    Sheriff
    Posts: 17626
    300
    Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Carey Brown wrote:Why not?


    Because the problem specifies "up to but not including the number"
     
    Carey Brown
    Saloon Keeper
    Posts: 10551
    83
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    static IntStream range(int startInclusive, int endExclusive)

    from javadocs
     
    Junilu Lacar
    Sheriff
    Posts: 17626
    300
    Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    You're right, this works, too:
     
    Slideshow boring ... losing consciousness ... just gonna take a quick nap on this tiny ad ...
    a bit of art, as a gift, the permaculture playing cards
    https://gardener-gift.com
    reply
      Bookmark Topic Watch Topic
    • New Topic