Nested for loop gives unexpected results - java

I was attempting to solve Puzzle A14 found at http://chortle.ccsu.edu/CPuzzles/PartA/CpuzzlesAsection11.html, using Java (with Eclipse), when I came across some unexpected results.
The puzzle requires that on each line k, print all of the integers that are multiples of 23 in the range of 100 * k to 100 * k + 99 (where k is some limit, such as 11).
The Nested For Loop that I eventually used to solve the problem was:
for(i = 0; i <= k; i++){
for(j = 0; j <= 99; j++){
if((100 * i + j) % 23 == 0)
System.out.print(100 * i + j + " ");
}
System.out.println();
}
However, in my first attempt, I did not put parentheses around 100 * i + j before using modulo division in the If Statement and it produced only one line of results: "0 23 46 69 92" (as compared to the correct solution, which gave me 11 lines of results: "0 23 46 69 92" in the first line, "115 138 161 184" in the second line, etc.).
I was trying to figured out the reason behind this. Even without the parentheses, I would assume the If Statement was using modular division on j, before combining it with 100 * i. However, if that was the case, wouldn't it produce 11 lines (if k = 11) of "0 23 46 69 92" instead of just a single line?

This is due to operator precedence. The modulo (%) operator as higher precedence over the plus and minus operators. See http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html.
Take, for example, the case where i = 1 and j = 38. In this case,
(100 * i + j) % 23 evaluates to zero and hence the condition is true. On the other hand, 100 * i + j % 23 evaluates to 115 and the condition is false.
The reason why only one line is printed when removing the parentheses is that when i > 0 (starting from the second line), the expression 100 * i + j % 23 will always be greater than 100, and therefore the condition of being equal to zero will always be false. Therefore, nothing will be printed starting at the second iteration of the outer for loop.

Because, for example, (100*1 + 15)%23 == 0 but 100*1 + 15%23 == 100*1 + (15%23) == 115.

Related

Recursion using modular arithmetic explain java

Could anyone explain how does this method works.
public static int calculate(int n){
if (n/10 == 0)
return n;
else
return (n % 10 + calculate(n/10));
}
I input n = 15 and it get a 6 but I don't understand how the method works. please help. thank you.
The method calculates the sum of the digits.
If the n is smaller than 10, you simply return n (since the sum of digits of a single digit number is the number itself).
Otherwise you add the least significant digit (that's n % 10) to the sum of digits of the number n / 10 (which is calculated recursively).
For n = 15 , here is how it works
15/10 > 0 , so the else condition is executed.
15%10 + calculate(15/10) i.e 5 + calculate(1).
The method is called again for n = 1;
Since 1/10 == 0 , 1 is returned
This 1 is then added to 5.
Therefore answer is 6.
So what this function does is return the sum of the digits that make up the number.
It goes like this:
calculate(15);
evaluates to
15%10 + calculate(1);
evaluates to
5 + 1;
which in the end; sums up to 6.
In other words; the above is an recursive approach to sum all the digits in a number. You could easily re-write this using a simple loop to avoid the recursion construct.
It cuts off the most right digit and moves on recursively with the rest of the number. (line 5)
If we have only one digit left (line 2), it is also added to the sum and the algorithm ends. (line 3)
In this example there is a if else condition so on the basis of input parameter there are 2 conditions '
-Firstly it checks in the if condition (n/10 == 0) .
-Consider your input as n=15.
now it checks if (n/10 == 0) i.e 15/10==0 which is false because 15/10=5 which is not equal to 0.
-As the condition is false it moves to else block where condition is to return
(n % 10 + calculate(n/10)
i.e. (15%10 +15/10)==5+1==6
-So the return is 6.

Loops in Java not adhering to the condition?

I've been scratching my head over why Java will go beyond a specified condition in some loops, while seemingly adhering to the condition in other loops. I know it's a lack of understanding on my part, but I'm confused as to when I should go over or adhere to the condition when I'm manually calculating code.
As an example, I've put in a short for loop which has an end result of 15 in iTotal, and 0 in iNumber. When I originally did the calculation on paper step by step, I ended up with the answers of 14 in iTotal, and 1 in iNumber. I assumed that the code would not go below one, as the condition was greater than zero, not equal to or greater than zero.
My original attempt -
iTotal
0
5
9
12
14
iNumber
5 4 3 2 1
int iTotal = 0;
for (int iNumber = 5; iNumber > 0; iNumber--)
iTotal = iTotal + iNumber;
In comparison, the below code snippet will at 19 with a condition of less than 20, with the last statement being value of x : 19. I calculated that correctly, but I'm not sure why the above code ignores the condition and goes to zero, while the below code adheres to the condition and stops at 19.
for(int x = 10; x < 20; x = x+1) {
System.out.print("value of x : " + x);
System..out.print(num2 + " " + num1);
Could anyone clarify how java interprets when to go over or stop at specified conditions?
In comparison, the below code snippet will at 19 with a condition of
less than 20, with the last statement being value of x : 19. I
calculated that correctly, but I'm not sure why the above code ignores
the condition and goes to zero, while the below code adheres to the
condition and stops at 19.
What you said is incorrect. The last statement printed is 19 but the last value of x is 20. This loop that you have given does in fact execute 20 times. A for loop in Java like the one you given has 3 components an integer to use as a count, a condition to test, and how to transform the count variable. In a general form it looks like this:
for(count variable, condition, transformation){
//Code goes here
//End loop
}
This for loops executes until the condition is no longer true, which is caused by applying a transformation of some sort the count variable.
Using the for loop you gave as an example:
for(int x = 10; x < 20; x = x+1) {
System.out.print("value of x : " + x);
System..out.print(num2 + " " + num1);
}
We create the count variable (int x) and set it equal to 10.
We check the count variable (int x) against the condition ( x<20 ) and evaluate the result, x < 20 == true so the code within the loop is run. At the end of the code, which I have marked "End Loop" above the transformation (x + 1) is applied to the count variable before the condition is tested again to see if the loop should proceed.
x = 11 now because x was equal to 10 but we added one as specified at the end of last loop. x < 20 == true is still true so the code within the loop will be executed again. This is continued in this way until the last number.
When x = 19 we test against the condition as we have been doing and see if x < 20 == true is still true, which it is so the code is executed. When the code execution ends, the count variable is again incremented, so x = 20.
With x = 20we once again test against x < 20. This time x < 20 == false so the code inside the loop is not executed nor is another transformation applied to the variable. At this point, when the condition becomes false the loop ends. So because we said x < 20 and not x <= 20 on the 20th loop, when x = 20, this code:
System.out.print("value of x : " + x);
System..out.print(num2 + " " + num1);
will not run. This means that the final output of the program would occur when x = 19 not when x=20 although if you were still able to access the count variable after the loop ends (which I believe you can do with a debugger) you would see x=20
The first loop does this:
iTotal = 0
iTotal = 5
iTotal = 9
iTotal = 12
iTotal = 14
iTotal = 15
Loop end
also as the first loops transformation is written as x-- instead of x - 1 the second loop can be rewritten as:
for(int x = 10; x < 20; x++) {
System.out.print("value of x : " + x);
System..out.print(num2 + " " + num1);
}
in Java the ++ operator increments by 1, it is the same as x+1.
Your first loop
for (int iNumber = 5; iNumber > 0; iNumber--)
iTotal = iTotal + iNumber;
is 5+4+3+2+1 = 15 (you must have printed iTotal before you added the first iNumber). Your second loop is similar the loop body isn't entered when the condition evaluates to false.
int x = 10;
for(; x < 20; x = x+1) {
System.out.print(x + " ");
}
System.out.println(x); // x is 20
as 10,11,12,13,14,15,16,17,18,19,20 but at twenty the loop terminates.
The condition is checked before each loop, not after. So in your first example, the logic would go:
iNumber = 5
first loop iteration
check iNumber > 0. 5 > 0, so continue the loop
add 5 to iTotal (iTotal=5 after this)
decrement iNumber
second loop iteration
check iNumber > 0. 4 > 0, so continue the loop
add 4 to iTotal (iTotal=9 after this)
decrement iNumber
...
fifth loop iteration
check iNumber > 0. 1 > 0, so continue the loop
add 1 to iTotal (iTotal=15 after this)
decrement iNumber
sixth loop iteration
check iNumber > 0. 0 > 0 is false, so break out of the loop
A similar process happens with the second loop.

Java: pre-,postfix operator precedences

I have two similar questions about operator precedences in Java.
First one:
int X = 10;
System.out.println(X++ * ++X * X++); //it prints 1440
According to Oracle tutorial:
postfix (expr++, expr--) operators have higher precedence than prefix (++expr, --expr)
So, I suppose that evaluation order:
1) first postfix operator: X++
1.a) X++ "replaced" by 10
1.b) X incremented by one: 10+1=11
At this step it should look like: System.out.println(10 * ++X * X++), X = 11;
2) second POSTfix operator: X++
2.a) X++ "replaced" by 11
2.b) X incremented by one: 11+1=12
At this step it should look like: System.out.println(10 * ++X * 11), X = 12;
3) prefix operator: ++X
3.a) X incremented by one: 12+1=13
3.b) ++X "replaced" by 13
At this step it should look like: System.out.println(10 * 13 * 11), X = 13;
4) evaluating 10*13 = 130, 130*11 = 1430.
But Java seems to ignore PRE/POST ordering and puts them on one level. So the real order:
X++ -> ++X -> X++
what causes the answer to be (10 * 12 * 12) = 1440.
Second one:
Example from this question:
int a=1, b=2;
a = b + a++;
Part of accepted answer:
"By the time of assignment, ++ has already incremented the value of a to 2 (because of precedence), so = overwrites that incremented value."
OK, let's look step-by-step:
1) replacing "b" with 2
2) replacing "a++" with 1
3) incrementing "a" by 1 -> at this point a==2
4) evaluating 2+1 = 3
5) overwriting incremented value of "a" with 3
Seems everything is fine.
But let's make a little change in that code (replace "=" with "+=")
a += b + a++;
steps 1-4 should be same as above.
so, after step 4 we have something like that:
a += 3;
where a==2
And then I think: OK, a = 2+3, so a should be 5. BUT the answer is only 4
I'm really confused. I already spent couple of hours but still can't understand where I am wrong.
P.S. I know, that I shouldn't use this "style" in real applications. I just want to understand what is wrong in my thoughts.
The confusion stems from the fact that the operands are evaluated from left to right. This is done first, before any attention is paid to operator precedence/order of operations.
This behavior is specified in JLS 15.7.2. Evaluate Operands before Operation
So X++ * ++X * X++ is first evaluated as 10 * 12 * 12 which yields, as you saw, 1440.
To convince yourself of this, consider the following:
X = 10; System.out.println(X++ * ++X);
X = 10; System.out.println(++X * X++);
If X++ were done first, then ++X second, then multiplication, both should print the same number.
But they do not:
X = 10; System.out.println(X++ * ++X); // 120
X = 10; System.out.println(++X * X++); // 121
So how does this make sense? Well if we realize that operands are evaluated from left to right, then it makes perfect sense.
X = 10; System.out.println(X++ * ++X); // 120 (10 * 12)
X = 10; System.out.println(++X * X++); // 121 (11 * 11)
The first line looks like
X++ * ++X
10 (X=11) * (X=12) 12
10 * 12 = 120
and the second
++X * X++
(X=11) 11 * 11 (X=12)
11 * 11 = 121
So why are prefix and postfix increment/decrement operators in the table?
It is true that increment and decrement must be performed before multiplication. But what that is saying is that:
Y = A * B++
// Should be interpreted as
Y = A * (B++)
// and not
Y = (A * B)++
Just as
Y = A + B * C
// Should be interpreted as
Y = A + (B * C)
// and not
Y = (A + B) * C
It remains that the order of the evaluation of the operands occurs left-to-right.
If you're still not conviced:
Consider the following program:
class Test
{
public static int a(){ System.out.println("a"); return 2; }
public static int b(){ System.out.println("b"); return 3; }
public static int c(){ System.out.println("c"); return 4; }
public static void main(String[] args)
{
System.out.println(a() + b() * c());
// Lets make it even more explicit
System.out.println(a() + (b() * c()));
}
}
If the arguments were evaluated at the time they were needed, either b or c would come first, the other next, and lastly a. However, the program outputs:
a
b
c
14
a
b
c
14
Because, regardless of the order that they're needed and used in the equation, they're still evaluated left to right.
Helpful reading:
What are the rules for evaluation order in Java?
a += a++ * a++ * a++ in Java. How does it get evaluated?
Appendix A: Operator Precedence in Java
In short,
Precedence is like preparing the expression to be calculated by putting parentheses. Evaluation comes next from left to right considering each pair of parentheses as a separate operation.
For example,if i=2 then i+i++ becomes i+(i++) after precedence and evaluates to 2+2 = 4.
However, i+++i becomes (i++)+i and evaluates to 2+3 = 5.
Same to i+(i=5) which evaluates to 2+5 = 7.
In fact the postfix operators do have higher precedence than prefix operators. For example, i+++++i becomes ((i++)++)+i after precedence which gives a compile error (the second postfix operator needs a variable to operate on but a value is found instead!). If both postfix and prefix operators had had equal precedence then the expression would have become (i++)+(++i) and evaluates to 2+4 = 6.
If you need more explanation you can compile and run the following code and inspect the examples printed at the output.
public class TestPrecedence {
public static void main(String[] str) {
int i = 0;
System.out.println("\n");
i = 2; System.out.println("i = " + i + "\n");
i = 2; System.out.println("i++ = " + i++ + "\n");
i = 2; System.out.println("++i = " + ++i + "\n");
i = 2; System.out.println("i++i = (i++)i TestPrecedence.java:8: error: ')' expected\n"+
" i++i\n"+
" ^\n");
i = 2; System.out.println("i+-i = i+(-i) = " + (i+-i) + "\n");
i = 2; System.out.println("++i++ = ++(i++) TestPrecedence.java:12: error: unexpected type\n"+
" ++i++ \n"+
" ^\n"+
" required: variable\n"+
" found: value\n");
i = 2; System.out.println("i+++++i = ((i++)++)+i TestPrecedence.java:17: error: unexpected type\n"+
" i+++++i\n"+
" ^\n"+
" required: variable\n"+
" found: value\n");
i = 2; System.out.println("i++ + ++i = " + (i++ + ++i) + "\n");
i = 2; System.out.println("i+(i=3) = " + (i+(i=3)) + " evaluates left to right\n");
i = 2; System.out.println("i+i++ precedence yields i+(i++) evaluates to 2+2 = " + (i+i++) + "\n");
i = 2; System.out.println("i+++i precedence yields (i++)+i evaluates to 2+3 = " + (i+++i) + "\n");
System.out.println("\n");
}
}
The reason why its 1440 is because
x is set to 10 i.e 1st term is FIXED(overall equation 10 *)
x is incremented by 1,x =11 now
x is pre-incremented by 1 x=12 and second term FIXED now (overall equation 10 * 12 *)
now x is set to 12 and third term FIXED(overall equation 10 * 12 *12)
x is increment now but is in this case not used for evaluation,
in short a term is FIXED when variable occurs which in this case is X
2nd case:
I'm not sure but I guess can be broken as,
a=b+a
a++
which I think is what is happening.
For the second one ->
int a=1, b=2;
a += b + a++;
Compiler will convert it to
a = a + b + a++;
Then apply your logic and you will find the reason why a is 4.
First step
1) first postfix operator: X++
1.a) X++ "replaced" by 10
1.b) X incremented by one: 10+1=11
At this step it should look like: System.out.println(10 * ++X * X++), X = 11;
2) prefix operator: ++X
2.a) X "replaced" by 11
2.b) X incremented by one: 11+1=12
At this step it should look like: System.out.println(10 * 12 * X++), X = 12;
3) second POSTfix operator: X++
3.a) X "replaced" by 12
3.b) X incremented by one: 12+1=13
At this step it should look like: System.out.println(10 * 12 * 12), X = 13;
This prints 10 * 12 * 12 = 1440
This is the bytecode for the first step
1. bipush 10
2. istore_0
3. getstatic java/lang/System/out Ljava/io/PrintStream;
4. iload_0
5. iinc 0 1
6. iinc 0 1
7. iload_0
8. imul
9. iload_0
10. iinc 0 1
11. imul
12. invokevirtual java/io/PrintStream/println(I)V
13. return
This do the following:
1. Push 10 to the stack
2. Pop 10 from the stack to X variable
3. Push X variable value (10) to the stack
5. Increment local variable X (11)
6. Increment local variable X (12)
7. Push X variable value (12) to the stack
8. Multiply top and subtop (10*12) Now Top = 120
9. Push X variable value (12) to the stack
10. Increment local variable X (13)
11. Multiply top and subtop (120*12) Now Top = 1440
Notice than the last increment (10.) is done after the push of X to the stack

Unexpected output from while loop Java

This is the class whose behaviour I am unable to understand.
class loop1 {
public static void main(String args[]) {
int i = 10;
do
while(i++ < 15) {
System.out.println(i);
i = i + 20;
System.out.println(i);
}
while(i<2);
System.out.println(i);
}
}
I expected it to print
11
31
31
But it prints
11
31
32
I am not able to understand why this "32" has come up in the output.
This is my understanding of the flow
i = 10
In the while loop because of unary incremental, it becomes 11 so this explains the first output
11 gets incremented to 31 by (+20)
Then 31 < 15 should fail (during the next iteration) so it should proceed to the last print statement and print 31, but it instead it is printing 32.
Can someone tell me what I am missing ?
During the final evaluation of the first while loop i++ still increments i even though the loop does not execute because the condition fails.
class loop1 {
public static void main(String args[]) {
//1. i = 10
int i = 10;
do
// 2. while loop condition = (10 < 15), i = 11
// 6. while loop condition = (31 < 15), i = 32
while(i++ < 15) {
System.out.println(i); //3. prints 11
i = i + 20; //4. i = 31
System.out.println(i); //5. prints 31
}
while(i<2); //this really has no effect on the codes execution, given i values
System.out.println(i); //7. Prints 32
}
}
i++
You're increasing the value by 1. The value, when you increase it after the first iteration is 31. 31 + 1 is, surprisingly, 32. And you print out the value directly after incrementing it.
In 2nd iteration when condition of while loop is check
while(i++<15)
at that time i is 31 so condition fail but i++ change the value of i 31 -> 32
while(i++ < 15) compare the value of i with and after that increment i by 1
My guess is:
while(i++ < 15)
The i++ increments the value from 31 to 32 on the second loop.
Note, the ++ will be executed even if the condition fails - which in your case, the 31 is greater than 15 (condition fails), however because of the ++ the value is incremented to 32, which is being printed out by the System.out at the end.
In the program :
while(i++<15)
above statement is condition checking in this statement
you are post increment i therefor 31+1=32 is comming

How to determine how often a statement in a nested loop is executed?

I am working through a section of a text on determining complexity of nested loops using recurrence relations. In this particular example I am trying to determine how many times the count variable will be incremented as a function of n.
This is the loop I am analyzing:
for (int i = 1; i <= n; i++) {
int j = n;
while (j > 0) {
count++;
j = j / 2;
}
}
I think I understand that the first line would equate simply to n since it only executes for each value of n but it's the rest of it that I'm having trouble with. I think the answer would be something like n(n/2) except that this example is using integer division so I'm not sure how to represent that mathematically.
I've run through the loop by hand a few times on paper so I know that the count variable should equal 1, 4, 6, 12, 15, and 18 for n values of 1-6. I just can't seem to come up with the formula... Any help would be greatly appreciated!
The loop executes for n in the range [1, n]. It divides by 2 each time for the j variable, which is set to n, so the number of time the inner loop executes is floor(l2(n)) + 1, where l2 is the binary log function. Add up all such values from 1 to n (multiply by n).
The inner j loop adds the location of the first set bit to count.
Each divide by 2 is the same as a right shift until all the bits are zero.
So, 2 would be 10 in binary, and have a value of 2 for the inner loop.
4 would be 100 in binary, and have a value of 3 for the inner loop.
The outer loop seems to just multiply the location of the first set bit by the number itself.
Here is an example with n = 13.
13 in binary is 1101, so the first set bit is at location 4.
4 * 13 = 52. 52 is the final answer.
for (int i = 1; i <= n; i++) {
This loop at the top goes through the loop n times.
int j = n;
while (j > 0) {
count++;
j = j / 2;
}
This loop here goes through the loop log(n) times, noting that it is a base 2 log since you are dividing by 2 each time.
Hence, the total number of counts is n * ceiling(log(n))

Categories