This week's book giveaway is in the Servlets forum. We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line! See this thread for details.

I'm attempting to create a program that does the following:

1. Use loops to complete the tasks below
2. Print out a list of all the numbers that meet the following criteria, one item per line.
3. Are either: Prime, or Multiples of 3, or 8, but not both 3 and 8, less than 2500umber

My code prints the multiples correctly but prints a bunch of erroneous prime numbers.

Here's my code:

My guess is that the problem is with my nested 'if' statement. I was reassured by finding an example online that looks a lot like the one I came up with, but mine doesn't seem to be working. Instead my result is stuff like this:

Jayeemsuh Allen wrote:My guess is that the problem is with my nested 'if' statement.

It is, but only partly.

Question: what is the result of (int)Math.sqrt(15)?

Now plug that into your loop and test it out on paper.

I'd also suggest that you might want to do your "divides by 3 or 8" check first, since if it turns up true, i can't possibly be prime.

Also:

I don't see any check for "divides by 3 AND 8" (check your requirements).

I don't see where you're limiting to 2500.

Winston

Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here

James Allen A.
Greenhorn

Joined: Mar 10, 2013
Posts: 24

posted

0

So I just did the Sq. Root of 15 on a calculator and I get ~3.8. Then "(int)" forces it to the integer 3. Isn't this the optimal way to test for primes? Aside from using the isPrime function? I have yet to use this function because I saw this method and wanted to attempt this first.

Good point about the order of my checks. Was caught on this prime check and didn't see that.

As for the limiting for loop (not sure the technical name for this), I just brought it down to 100 to minimize the output while test running it.

As for being divisible by 3 AND 8, I don't the wording of the challenge suggests that, saying

Are either: Prime, or Multiples of 3, or 8, but not both 3 and 8, less than 2500

Jayeemsuh Allen wrote:So I just did the Sq. Root of 15 on a calculator and I get ~3.8. Then "(int)" forces it to the integer 3. Isn't this the optimal way to test for primes?

Did you test it out on paper like I suggested? What happens when you put 3 through your loop? Far better that you SEE what happens than me telling you.

As for being divisible by 3 AND 8, I don't the wording of the challenge suggests that...

OK, well what do you think should happen for 24? Should it be printed out or not?

And what about 9? ... Or 16? ...

Test your program. I can't stress enough how important it is to do that.

Winston Gutkowski wrote:
Test your program. I can't stress enough how important it is to do that.

"Stress test" comes to one's mind ;-)

James Allen A.
Greenhorn

Joined: Mar 10, 2013
Posts: 24

posted

0

Okay so I pulled out a notebook and you're right, much easier to make sense of things. I was struggling with how to discern whether a number is prime or not while keeping the for loop going to try all divisors. I'm not sure if this is the most efficient way, but I created a counter variable for number of divisors and then added my if statement after the for loop to print the prime number as long as numDivisors == 0. This seems to print the desired numbers.

1
I'm interpreting the wording of the challenge to mean "print all multiples of 3 and all multiples of 8, omit numbers that are multiples of 3 and 8" I believe the code does this. Adding: was an experiment but it seems to work. I don't totally understand why though. Is it because the || operator is exclusive from the && operator? Does that make sense?

Jayeemsuh Allen wrote:I was struggling with how to discern whether a number is prime or not while keeping the for loop going to try all divisors. I'm not sure if this is the most efficient way,...

It isn't.

...but I created a counter variable for number of divisors and then added my if statement after the for loop to print the prime number as long as numDivisors == 0. This seems to print the desired numbers.

Actually, it has nothing to do with that (although there's nothing specifically wrong with with it). The reason it now works is that you've changed the condition in your loop from what it was before.

I'm interpreting the wording of the challenge to mean "print all multiples of 3 and all multiples of 8, omit numbers that are multiples of 3 and 8" I believe the code does this. Adding: was an experiment but it seems to work. I don't totally understand why though.

Because you're too fixated on HOW you're going to do it, rather than WHAT needs to be done.

Go back to your original statement: "print all multiples of 3 and all multiples of 8, omit numbers that are multiples of 3 and 8". This is what you want to be working with.

Tip: Add this to your code immediately after your for loop statement:
boolean multipleOf3 = (i > 3 && i % 3 == 0); boolean multipleOf8 = (i > 8 && i % 8 == 0);

And now try re-writing that logic using multipleOf3 and multipleOf8.
Doesn't it look much more like the statement you wrote?

Part of the art of programming is making things easy to read. And I suspect you'll now KNOW that the logic works - you won't have to guess - because it's simple.

I believe the code does this. Adding:
if (i % 3 != 0 || i % 8 != 0) {
was an experiment but it seems to work. I don't totally understand why though. Is it because the || operator is exclusive from the && operator? Does that make sense?

Adding code that you don't fully understand in the hope that it might work is not the best way to go about solving a problem.
The if statement says execute the following code if 'i' is not divisible by 3 or it is not divisible by 8. So the if statement will only evaluate to false if 'i' is divisible by both 3 and 8. Hence numbers divisible by both 3 and 8 are ignored.

James Allen A.
Greenhorn

Joined: Mar 10, 2013
Posts: 24

posted

0

Okay I re-wrote the program using boolean variables like Winston suggested. Is this what you're suggesting? It seems to work.

Perhaps because I'm a beginner -- or because I'm me -- but I'm not seeing how this clearly translates to the objective of my challenge. Maybe this will become more second nature to me as I understand how to program in Java more efficiently?

following for-loop will present prime numbers between 0 and 2500. so why did you struggle with Math.sqrt(i); ?

I guess this is the most efficient way to get primes.

Are you better than me? Then please show me my mistakes..

Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2158

47

posted

0

Supun Lakshan Dissanayake wrote:following for-loop will present prime numbers between 0 and 2500. so why did you struggle with Math.sqrt(i); ?

I guess this is the most efficient way to get primes.

No it won't give only prime numbers.
If you run your code you will get:

1 is a prime number
5 is a prime number
7 is a prime number
11 is a prime number
13 is a prime number
17 is a prime number
19 is a prime number
23 is a prime number
25 is a prime number
29 is a prime number
31 is a prime number
35 is a prime number
...

which shows 3 false values in the first 12 results (as well as missing out a few)

Supun Lakshan Dissanayake wrote:following for-loop will present prime numbers between 0 and 2500. so why did you struggle with Math.sqrt(i); ?

I guess this is the most efficient way to get primes.

No it won't give only prime numbers.
If you run your code you will get:

1 is a prime number
5 is a prime number
7 is a prime number
11 is a prime number
13 is a prime number
17 is a prime number
19 is a prime number
23 is a prime number
25 is a prime number
29 is a prime number
31 is a prime number
35 is a prime number
...

which shows 3 false values in the first 12 results (as well as missing out a few)