I'm struggling with this task. User is providing numbers L1 and L2. Add all odd numbers from range L1,L2 and all even numbers from this range and display the sums. I have to make it in 3 ways, using: for, while and do while loops. My for loop works perfectly, but while is displaying some higher scores.
import java.util.Scanner;
public class PPO4b {
public static void main(String[] args) {
Scanner value1Check = new Scanner(System.in);
System.out.println("Provide first value: ");
int value1 = value1Check.nextInt();
Scanner value2Check = new Scanner(System.in);
System.out.println("Provide second value: ");
int value2 = value2Check.nextInt();
int sumOdd = 0;
int sumEven = 0;
int i = 0;
while (i <= 0) {
if (i % 2 == 1) {
sumOdd = sumOdd + i;
} else {
sumEven = sumEven + i;
}
i = i + 1;
}
System.out.println("Sum is equal to: " + sumEven);
System.out.println("Sum is equal to: " + sumOdd);
}
}
With your current approach here are some observations.
You only need one Scanner.
You are testing i
for parity where you should be testing the input range
e.g should be something like:
while (value1 <= value2) {
if (value1 % 2 == 1) {
sumOdd = sumOdd + value1;
don't forget to increment value1
When printing, don't label each sum with just sum
. Use a descriptive name
Alternative approach
With a little math you can do this in O(1)
time.
1 thru n
values, n(n+1)/2)
will give the sumk thru n
values, (n-k+1)(n+k)/2
will give the sum of those values.2 3 4 5 6
. The total number of even values is 3
which are 2, 4, and 6
. This is true even if you have 1 2 3 4 5 6 7
.s
, the next one lower is ((s-1)
. So if s = 4
would be 3
s
, the next lower one would be (s-1)|1
. So for s == 4
, (s-1) = 3 and 3|1 == 3
. The OR
simply sets the low order bit to make the value odd or let it stay odd.e
, e|1
will be either the same odd value or the next highest.Now there is enough information to compute the sum of the even
and odd
values between s and e
.
For given int e and int s;
int totalSum = ((e+s)*(e-s+1))/2;
e = (e|1);
s = (s-1)|1;
int evenCount = (e-s)/2;
int sumEven = ((e - s + 1) * (evenCount))/2;
int sumOdd = totalSum - sumEven;
Here is how to verify it.
IntStream
of the ranges, filtering out even and odd values as appropriateRandom rnd = new Random();
for (int i = 0; i < 200000; i++) {
int s = rnd.nextInt(200) +100;
int e = rnd.nextInt(500) + s;
int compEven = IntStream.rangeClosed(s, e)
.filter(r -> r % 2 == 0).sum();
int compOdd = IntStream.rangeClosed(s, e)
.filter(r -> r % 2 == 1).sum();
int totalSum = (e + s) * (e - s + 1) / 2;
e |= 1;
s = (s - 1) | 1;
int evenCount = (e - s + 1) / 2;
int evenSum = ((e + s) * evenCount) / 2;
int oddSum = totalSum - evenSum;
if (evenSum != compEven || oddSum != compOdd) {
System.out.println("Oops - sums don't match");
}
}
Note: depending on the range you may need to use long or BigInteger types to avoid overflow.