These are the solutions to the mock exam of Mon in class. 

1. fun(4) evaluates to 7

2. fun(5) never ends

Here's how you can prove both statements:

-bash-4.1$ ls -l One.java
-rw-r--r-- 1 dgerman www 343 Jan 29 12:57 One.java
-bash-4.1$ cat One.java
public class One {
  public static void main(String[] args) {
    System.out.println( One.fun( 4 ) );
  }

  static int fun(int m) {
    System.out.println("Being called with: " + m);
    int n = 0;
    if (m == 0) {
      n = 1;
    } else {
      n = m + fun(m - 2);
    }
    System.out.println("Returning: " + n);
    return n;
  }

}
-bash-4.1$ javac One.java
-bash-4.1$ java One
Being called with: 4
Being called with: 2
Being called with: 0
Returning: 1
Returning: 3
Returning: 7
7
-bash-4.1$


If you call fun(5) it recursively calls fun with smaller arguments: 3, 1, -1, -3, -5, ... and so on. 

Since these miss 0 (zero) the recursive calls will never reach a fixed point, so they will never end. 

3. Math.random() produces random values uniformly distributed in the interval [0, 1); that's a given. 

The expression Math.random() * 7 produces values uniformly distributed in the interval [0, 7) 

So  Math.random() * 7  + 6  will produce values uniformly distributed in the interval [6, 13)

So the answer is: 5

A proof of sorts can be obtained as follows: 

-bash-4.1$ ls -ld Two.java
-rw-r--r-- 1 dgerman www 556 Jan 29 13:19 Two.java
-bash-4.1$ cat Two.java
import java.util.*;

public class Two {
  public static void main(String[] args) {
    Map<Integer, Integer> histogram = new HashMap<Integer, Integer>();
    for (int i = 0; i < Integer.parseInt( args[0] ); i++) {
      Integer a = Two.genValue();
      if (histogram.containsKey( a )) {
        histogram.put( a , histogram.get( a ) + 1 );
      } else {
        histogram.put( a , 1 );
      }
    }
    System.out.println( histogram );
  }

  public static int genValue() {
    int x = (int)(Math.random() * (12 - 5) + 6);
    return x;
  }
}
-bash-4.1$ javac Two.java
-bash-4.1$ java Two 10
{7=3, 8=1, 9=3, 10=1, 12=2}
-bash-4.1$ java Two 100
{6=12, 7=15, 8=17, 9=9, 10=16, 11=12, 12=19}
-bash-4.1$ java Two 1000
{6=138, 7=150, 8=132, 9=129, 10=145, 11=152, 12=154}
-bash-4.1$ java Two 10000
{6=1425, 7=1399, 8=1417, 9=1473, 10=1394, 11=1429, 12=1463}
-bash-4.1$ java Two 100000
{6=14307, 7=14233, 8=14310, 9=14364, 10=14185, 11=14329, 12=14272}
-bash-4.1$

Notice when we produce only 10 values 6 and 11 don't even get produced. 

The more values we produce the more obvious the expected uniform distribution. 

So the only values produced are: 6, 7, 8, 9, 10, 11, 12. 

4. The right answer is: (b). 

In other words 

    !(x % 4 != 0 || !(x % 100 == 0 && x % 400 == 0))

is equivalent to: 

    ((x % 400) == 0)

But it's not equivalent to: 

    ((x % 100) == 0)

    ((x % 100) != 0)

    ((x % 400) != 0)

You can prove this with DeMorgan: 


    !(x % 4 != 0 || !(x % 100 == 0 && x % 400 == 0))

is the same as 

      x % 4 == 0 && (x % 100 == 0 && x % 400 == 0)

which is

      x % 4 == 0 && (x % 400 == 0)

which is

      x % 4 == 0 && x % 400 == 0

which is

      x % 400 == 0

To prove it with a program you could randomly generate integers x. 

Then feed them in all five expressions. 

You should obtain counterexamples in all but one case, hence the clue. 

5. Exercises of this kind could be formulated as follows: rewrite the code unambiguously. 

In this case for exercise 5 we have

    int x = 18, y = 10; if (x < 10) { if (x > 5) y = 1; } else y = 2;

This can be written unambiguously as follows: 

    int x = 18, 
        y = 10; 
    if (x < 10) { 
      if (x > 5) {
        y = 1; 
      } else { 

      }
    } else { 
      y = 2;
    } 

Which means that y will be 2 at the end. 

Proof: 

-bash-4.1$ cat Three.java
import java.util.*;

public class Three{
  public static void main(String[] args) {
    {
      int x = 18, y = 10; if (x < 10) { if (x > 5) y = 1; } else y = 2;
      System.out.println( y ); // should be 2
    }
    {
      int x = 18, y = 10; if (x < 10) if (x > 5) y = 1; else y = 2;
      System.out.println( y ); // should be 10
    }
    {
      int x = 18, y = 10; if (x < 10) { if (x > 5) y = 1; else y = 2; }
      System.out.println( y ); // should be 10
    }

  }
}
-bash-4.1$ javac Three.java
-bash-4.1$ java Three
2
10
10
-bash-4.1$

So this code also gave away the answers to the next two problems. 

6. The answer is 10 because the code can be written unambiguously as follows: 

    int x = 18, 
        y = 10; 
    if (x < 10) {  
      if (x > 5) { 
        y = 1; 
      } else { 
        y = 2;
      } 
    } else {

    } 

So we don't change y and it remains what it was. 

7. The code can unambiguously be written as follows:

    int x = 18, 
        y = 10; 
    if (x < 10) { 
      if (x > 5) { 
        y = 1; 
      } else { 
        y = 2; 
      } 
    } else { 

    } 

So that's identical to the previous exercise. 

8. If you try to arrange the code in standard form (unambiguously) you can't finish: it doesn't compile. 

    int x = 8, y = 0; { if (x < 10) if (x > 5) y = 1; } else y = 2;

This amounts to 

    int x = 8, 
        y = 0; 
    { 
      if (x < 10) { 
        if (x > 5) { 
          y = 1; 
        } else { 

        } 
     } else { 

     } 
    } else { // error: else without if 
      y = 2; 
    } 

So all looks good up until that line which has to deal with an else for which there is no active if statement to attach to. 

9. i will start at -10 and be -7, -4, -1, 2, 5, 8 in order. 

Every time a ? is printed so 7 of them. When i becomes 10 we're kicked out. 

10. i will start as 7, then become 6, 5, 4, 3, 2, 1, 0 in succession. 

For each we see a question mark, so: 8. When i becomes -1 we're out. 

11., 12.: x and y have their values swapped. 

This is equivalent to: 

  int x = ..., y = ..., u; 

  u = x; 

  x = y; 

  y = u; 

Though in our code we don't need a third variable. 

13. The program prints 6 twice. 

The key is in how i++ works: 

(a) first i is evaluated
(b) then i is modified (incremented by 1)
(c) then the value obtained at (a) is used as indicated in the program

Thus: 

  i = i++; 

actually does the following:

  (a) i is 6 at that point in the program
  (b) then i becomes 7
  (c) the 6 is placed in i

Then i is printed for the second time. 

Here's how you can convince yourself that things work as described: 

  int i = 3, j = 5, a; 

  a = i++ + j++;

  System.out.printn( a ); // prints 8
  System.out.printn( i ); // prints 4
  System.out.printn( j ); // prints 6

So please use expressions like i++ judiciously/appropriately. 

For example please note that i++ is not equivalent with i = i + 1

If it were they would print the same. 

For example if we take: 

-bash-4.1$ cat Four.java
import java.util.*;

public class Four{
  public static void main(String[] args) {

    int i = 6;

    i = (i = i + 1); // this is not equivalent to i = i++; 

    System.out.println( i ); // prints 7

  }
}
-bash-4.1$ javac Four.java
-bash-4.1$ java Four
7
-bash-4.1$

So be careful how you use i++ in your code. 

14., 15., 16. are straightforward. Here are the answers: 

-bash-4.1$ cat Five.java
class Five {
  public static void main(String[] args) {
    {
      String plum = "coconut";
      System.out.println(plum.substring(0, "plum".length()));
    }

    {
      String plum = "coconut";
      System.out.println((char)('Q' - plum.length()));
    }

    {
      String plum = "nectarine";
      System.out.println((char)('Q' - "plum".length()));
    }
  }
}
-bash-4.1$ javac Five.java
-bash-4.1$ java Five
coco
J
M
-bash-4.1$

Notice the first expression was missing a paren ) at the end but if we add it it prints "coco". 

Otherwise that expression doesn't compile. That was not on purpose, just accidental. 

J is 7 letters ahead of Q in the alphabet: J K L M N O P Q

M is 4 letters ahead of Q in the alphabet. 

17. Somebody yesterday remarked this looked like Scheme and if you replace kanga with plus and ru with minus we have: 

    (kanga(kanga(kanga(kanga(ru(1, 2), 
                             1), 
                       2), 
                 ru(1, 2)), 
           1));


which is  (plus (plus (plus (plus (minus 1 2)
                                  1)
                             2)
                      (minus 1 2)) 
                1)

which is  (plus (plus (plus (plus -1
                                  1)
                             2)
                      (minus 1 2)) 
                1)

which is  (plus (plus (plus 0
                            2)
                      (minus 1 2))
                1)

which is  (plus (plus 2 
                      (minus 1 2))
                1)

which is  (plus (plus 2 -1) 1)

which is  (plus 1 1)

which is 2

Proof: 

-bash-4.1$ cat Six.java
class Six {
  public static void main(String[] args) {
    System.out.println(kanga(kanga(kanga(kanga(ru(1, 2), 1), 2), ru(1, 2)), 1));
  }
  public static int kanga(int a, int b) {
    return a + b;
  }
  public static int ru(int a, int b) {
    return a - b;
  }
}
-bash-4.1$ javac Six.java
-bash-4.1$ java Six
2
-bash-4.1$

18 is simple: 

-bash-4.1$ pico -w Seven.java
-bash-4.1$ javac Seven.java
-bash-4.1$ java Seven
2
-bash-4.1$ cat Seven.java
class Seven {
  public static void main(String[] args) {
    System.out.println(fun(fun(fun(fun(6))))); // subtracts 1 4 times from 6: prints 2
  }
  static int fun(int value) {
    return value - 1;
  }
}
-bash-4.1$

19 is also straightforward: 

's' + 't' + "ew" is 115 + 116 + "ew" which is (115 + 116) + "ew" which is "231ew"

See: http://www.asciitable.com/index/asciifull.gif

-bash-4.1$ pico -w Eight.java
-bash-4.1$ javac Eight.java
-bash-4.1$ java Eight
231ew
-bash-4.1$ cat Eight.java
class Eight {
  public static void main(String[] args) {
    String tsew = "stue".charAt(0) + "tsue".charAt(0) + "ew";
    System.out.println(tsew);
  }
}
-bash-4.1$

In 20 you can tell that the method interleaves the input strings.

So the result is   ('b' + 'a' + ('b' + 'a' + ('b' + 'a' + "")))  can you calculate that? 

It's not "bababa". So, what is it? Here's the answer:

-bash-4.1$ ls -ld Nine.java
-rw-r--r-- 1 dgerman www 517 Jan 29 15:13 Nine.java
-bash-4.1$ cat Nine.java
class Nine {
  public static void main(String[] args) {

    System.out.println(  ('b' + 'a' + ('b' + 'a' + ('b' + 'a' + "")))  );

    System.out.println( mix("bbb", "aaa") );
    System.out.println( mix("bbb", "aaaaaa") );

  }
  public static String mix(String one, String two) {
    String answer = "";
    int lengthOne = one.length(), lengthTwo = two.length();
    for (int i = 0; i < lengthOne && i < lengthTwo; i++) {
      answer = one.charAt(i) + two.charAt(i) + answer;
    }
    return answer;
  }
}
-bash-4.1$ javac Nine.java
-bash-4.1$ java Nine
195195195
195195195
195195195
-bash-4.1$

The code above answers all three questions. 

Why is 'b' + 'a' + "" printing 195? 

22. Initially count is zero so the loop doesn't even start. Not infinite loop because we don't even start it. 

With different initial values of count it could be infinite. 

23. Again, the loop does not even start: 

int count = 0; 
count = count + 1; 
while (! (count > 0)) {
  System.out.println( count ); 
  count = count + 1; 
}


24. Infinite loop because count starts as -1, we enter the loop, then count gets decreased by 1 every time around the loop. 

25. The answer is: (d)

All the others (and the given while) calculate 0 + 2 + 4 + 6 + 8 + ... + 92 + 94 + 96 + 98 == 1225

And here's how they do it: 

  i   sum   i < 100 
---------------
  0    0    0 < 100 true
       0 + 0
  2         2 < 100 true 
       0 + 0 + 2
  4         4 < 100 true 
       0 + 0 + 2 + 4 
  6         6 < 100 true 
      ...
       0 + 0 + 2 + 4 + ... + 92 + 94
 96        96 < 100 true 
       0 + 0 + 2 + 4 + ... + 92 + 94 + 96
 98        98 < 100 true
       0 + 0 + 2 + 4 + ... + 92 + 94 + 96 + 98
100       100 < 100 false        

The code at (d) however calculates 0 + 2 + 4 + 6 + 8 + ... + 92 + 94 + 96 + 98 + 100 == 1325 (so adds one extra element, 100). 

26. If statement so it's not a loop, it's an if statement (not a while or for). 

27. Infinite loop because i is 0, 3, 6, 9, 12, ... so it skips 10 and it never ends. 

Careful then how you formulate your termination conditions!

28. Not an infinite loop since i grows and when it becomes 10 or bigger the loop stops. 

29. In this loop i starts as 0. 

We print 0, make it  3, then take one out:  2, and check. 
We print 2, make it  5, then take one out:  4, and check. 
We print 4, make it  7, then take one out:  6, and check. 
We print 6, make it  9, then take one out:  8, and check. 
We print 8, make it 11, then take one out: 10, and check. Stop. 


30. Not equivalent. Consider x = 5. 

The first fragment turns x into 6 by incrementing it by 1. 

The second one first increments it to 6 then sets it to 8. 

So this one counterexample is enough to distinguish them. 

--