CS 1401, Exam #2, 11:30 am version

Date: Friday, October 12, 2007
Name (please type legibly, ideally in block letters): ______________________________________________________________________

On October 12, 1709, La Villa de San Francisco de Cuellar was founded. This town later became San Felipe del Real Chihuahua and is now known as Cd. Chihuahua.

1. The Vice-Roy received three reports about the new city, with slightly different estimates of its population. To brag to the King of Spain, he selected the largest of these estimates. Use if-statements to write down a code that, given three numbers pop1, pop2, and pop3 describing the three estimates, computes and prints the largest value.

Hint: You do not need to read anything from the keyboard or from a file, just compute and print. Assume that pop1, pop2, and pop3 have been assigned some values already.


Solution:

int largest;
if (pop1 >= pop2 && pop1 >= pop3)
  largest = pop1;
else if (pop2 >= pop1 && pop2 >= pop3)
  largest = pop2;
else
  largest = pop3;
System.out.println(largest);

2. The name of the town was decided by voting. Some people wanted to name is San Diego, some San Francisco. Just in case, the city founders prepared two reports to the Vice-Roy, with two different names. Write down a code that, given two strings s1 and s2 containing these reports and the final name of the town (stored in the string town), finds the string which contains this name and places it first.

Example: if s1 is "We called the town San Diego", s2 is "We called the town San Francisco", and town is "San Francisco", then after your code, s1 should contain "We called the town San Francisco" and s2 should contain "We called the town San Diego".

Trace your code, step by step, on this example: draw all the boxes and show how their values change after each operation.

For extra credit: make the code work also if the name is spelled in all caps.


Solution:

if (s2.indexOf(town) >= 0)
  {String temp = s1;
   s1 = s2;
   s2 = temp;
  }

Tracing:

originally

 --------    -------   -------   ---------------
|  22    |  |   33  | |   44  | | San Francisco |
 --------    -------   -------   ---------------
   s1           s2      town         44

 -------------------------------
| We called the town San Diego  |
 -------------------------------
                 22

 ----------------------------------
| We called the town San Francisco |
 ----------------------------------
                 33

after the line String temp = s1:

 --------    -------   -------   ---------------   ------
|  22    |  |   33  | |   44  | | San Francisco | |  22  |
 --------    -------   -------   ---------------   ------
   s1           s2      town          44            temp

 -------------------------------
| We called the town San Diego  |
 -------------------------------
                 22

 ----------------------------------
| We called the town San Francisco |
 ----------------------------------
                 33

after the line s1 = s2;

 --------    -------   -------   ---------------   ------
|  33    |  |   33  | |   44  | | San Francisco | |  22  |
 --------    -------   -------   ---------------   ------
   s1           s2      town          44            temp

 -------------------------------
| We called the town San Diego  |
 -------------------------------
                 22

 ----------------------------------
| We called the town San Francisco |
 ----------------------------------
                33

after the line s2 = temp;

 --------    -------   -------   ---------------   ------
|  33    |  |   22  | |   44  | | San Francisco | |  22  |
 --------    -------   -------   ---------------   ------
   s1           s2      town          44            temp

 -------------------------------
| We called the town San Diego  |
 -------------------------------
                 22

 ----------------------------------
| We called the town San Francisco |
 ----------------------------------
                33

Extra credit:

if (s2.toLowerCase().indexOf(country.toLowerCase()) >= 0)
  {String temp = s1;
   s1 = s2;
   s2 = temp;
  }

3. To participate in the voting in 1709, a person must be male (female did not vote until late 19 and 20 century), not younger than 16, and spend at least 1 year in America. Describe a Java expression describing the right to vote. Draw the truth tables for "and", "or", and "not" operations. Use these truth tables to find the truth value of your expression for Senora Malinche III, who is female, 18 years old, and spent all these 18 years in the Americas. Explain precedence of different logical operations, and how this precedence is related to precedence of different arithmetic operations.


Solution:

male && !(age < 16) && (yearsInAmerica >= 1.0)

------------------------------------
| A |  B | A and B | A or B | not A |
 ------------------------------------
| F |  F |    F    |   F    |   T   |
 ------------------------------------
| F |  T |    F    |   T    |   T   |
 ------------------------------------
| T |  F |    F    |   T    |   F   |
 ------------------------------------
| T |  T |    T    |   T    |   F   |
 ------------------------------------

male is False; age is 18 so age < 16 is False; yearsInAmerica is 18.0,
so yearsInAmerica >= 1.0 is True; so, the above expression becomes
F && !F && T. According to the truth table, !F is T. Thus, the formula
is F && T && T, i.e., False.

Precedence: negation ! has the highest precedence, then &&, then ||.

Inside the computer, True is 1, False is 0, so && is actually
multiplication. Or is almost addition, and precedence for && and ||
is the same as for multiplication and addition.

4. For tax purposes, the data about the citizens of the town is stored in a file tax.asc. Use the while loop to find and print the line that contains a given name. Trace your code on the example of a file in which the first line is "Senor Cortes III: 100 pesos" and the second is "Senora Malinche: 60 pesos". (Women could not vote but they still had to pay taxes.)

Reminder: to create an object for reading from a file, you need to use the following code:

Scanner fromFile = new Scanner(new FileReader("tax.asc"));

Solution:

Scanner fromFile = new Scanner(new FileReader("tax.asc"));
Boolean found = false;
String line;
while(!found && fromFile.hasNext()){
  line = fromFile.next():
  if (line.indexOf("Malinche") >=0){
    System.out.println(line);
    found = true;
  }
}

At first, "found" is false. Since !found is true and there is something
in the file (i.e., fromFile.hasNext() is true), we go into the file
and read the first line of the file into the variable "line".

The value of "line" is now the first line of the file, i.e.,
"Senor Cortes III: 100 pesos". This string does not contain a substring
"Malinche", so line.indexOf("Malinche") is -1. The condition
line.indexOf("Malinche") >=0 is not satisfied, so we do not do
anything on this iteration and continue looping.

The value of found is still false, there is still something in the file,
so we read the next line "Senora Malinche: 60 pesos" into the variable
"line". This time, the string contains a substring "Malinche", and the
value of line.indexOf("Malinche") is 7. The condition
line.indexOf("Malinche") >=0 is satisfied, so we print the
string "Senora Malinche: 60 pesos" and change the value of the
variable "found" to "true".

On the next iteration, !found is false, so the condition for continuing
is false, so we get out of the loop.

5. To convert a decimal integer n to binary form, you repeatedly divide n by 2 and keep the remainder until you get 0. Reading the remainders from bottom to top provides the desired binary number. Use this algorithm to convert 17 and 9 to binary code. Check the results by converting the binary number back into the decimal code.

Reminder: 137 in decimal code means 1 * 10^2 + 3 * 10^1 + 7 * 10^0. Similarly, 101 in binary code means 1 * 2^2 + 0 * 2^1 + 1 * 2^0 = 1*4 + 0*2 + 1*1 = 4 + 1 = 5.


Answer:

17 / 2 = 8 rem 1
 8 / 2 = 4 rem 0
 4 / 2 = 2 rem 0
 2 / 2 = 1 rem 0
 1 / 2 = 0 rem 1

When we read the remainders from bottom to top, we get 10001. In
binary code, it means 1 * 2^4 + 0 * 2^3 + 0 * 2^2 + 0 * 2^1 + 1 * 2^0 =
1 * 16 + 0 * 8 + 0 * 4 + 0 * 2 + 1 * 1 = 16 + 1 = 17.

 9 / 2 = 4 rem 1
 4 / 2 = 2 rem 0
 2 / 2 = 1 rem 0
 1 / 2 = 0 rem 1

When we read the remainders from bottom to top, we get 1001. In
binary code, it means 1 * 2^3 + 0 * 2^2 + 0 * 2^1 + 1 * 2^0 =
1 * 8 + 0 * 4 + 0 * 2 + 1 * 1 = 8 + 1 = 9.