Java au Naturel Solutions to Text Book Questions

Unit 8 / Exercise 3.23 / Exercise 3.24 /

Exercise 3.25**

/ Exercise 3.30* / Exercise 3.31* / Exercise 3.32* / Exercise
3.33** / Exercise
3.34** / Exercise 3.37 / Exercise 3.38*
Unit 9 / Exercise 4.1* /

Exercise 4.2*

Unit 10 / Exercise 4.5* / Exercise 4.6* / Exercise 4.16* / Exercise 4.17* / Exercise 4.18* / Exercise 4.19* / Exercise 4.20**
Unit 11 / Exercise 4.26* / Exercise 4.27* /
Exercise 4.28*
/ Exercise 4.29* / Exercise 4.32* / Exercise 4.33* / Exercise 4.34** / Exercise
4.37* / P
R
O
J
E
C
T
Unit 12 / Exercise 5.4* / Exercise 5.5* / Exercise 5.6** / Exercise 5.9* / Exercise 5.10* / Exercise 5_12 / Exercise 5.13* / Exercise 5.15* / Project
Unit 8 - Assignments - 30 Marks
Exercise 3.23*: Write a Looper method public void bringBack(): The executor removes the CD in its current slot, if any, then brings each CD that is later in the sequence back one slot. Leave the position of the executor unchanged.
public void bringBack()
{ String spot = this.getPosition();
if (this.seesCD())
this.takeCD();
while (this.seesSlot())
{ if (this.seesCD())
{ this.takeCD();
this.backUp();
this.putCD();
}
this.moveOn();
}
backUpTo (spot);
} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/** Back up to the specified position. Precondition:
* someSpot records a slot at or before the current slot. */
private void backUpTo (String someSpot)
{ while (! someSpot.equals (getPosition()))
backUp();
} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Exercise 3.24*Compare the coding of seesAllFilled in Listing 3.5 with the coding of hasSomeFilledSlot in the earlier Listing 3.2. Note that the only material difference is the presence or absence of the not-operator in two places. If both places had the not-operator, what would be a good name and comment heading for the resulting method? What would they be if neither place had the not-operator?
If both places had the not operator, a good name would be: seesAllEmpty(). The comment heading would be:
/** Tell whether every slot here and later is empty. */
If neither places had the not operator, a good name would be: hasSomeEmptySlot().
The comment heading would be:
/** Tell whether any slot here or later is empty. */


Exercise 3.32*Write a query method public boolean matches (Vic par) for Looper: The executor tells whether it has a CD wherever the parameter has a CD and it does not have a CD wherever the parameter does not. That is, the two sequences of slots are the same in terms of the presence of CDs, starting from the current slot in each.
public boolean matches (Vic par)
{ String thisSpot = this.getPosition();
boolean result = (this.seesCD() & par.seesCD()) || (! this.seesCD()
& ! par.seesCD());
while (this.seesSlot() & par.seesSlot())
{ if ((! this.seesCD() & par.seesCD()) || (this.seesCD()
& ! par.seesCD()))
{ result = false;
break;
}
this.moveOn();
par.moveOn();
}
while (! thisSpot.equals (this.getPosition()))
{ this.backUp();
par.backUp();
}
return result;
} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Exercise 3.33** Write a method public void shiftOne (Vic one, Vic two) for a subclass of Vic: At each position where the executor has an empty slot and either of the two Vic parameters has a filled slot in the orresponding position, shift the CD to the executor's slot. When a choice is possible, take a CD from the first parameter's slot.
public void shiftOne (Vic one, Vic two)
{
while (this.seesSlot() & one.seesSlot() || this.seesSlot() & two.seesSlot())
{
if ( ! this.seesCD() & one.seesSlot() & one.seesCD())
{
one.takeCD();
this.putCD();
}
if ( ! this.seesCD() & two.seesSlot() & two.seesCD())
{
two.takeCD();
this.putCD();
}
this.moveOn();
if (one.seesSlot())
one.moveOn();
if (two.seesSlot())
two.moveOn();
}
} //======
Exercise 3.34** Write a query method public boolean sameNumber (Vic par) for Looper: The executor tells whether it has the same number of CDs in its slots as the Vic parameter. Do not use numeric variables. Hint: Advance each to the next nonempty slot. Repeat this until one runs out of slots. Does the other?.
public boolean sameNumber (Vic par)
{ String thisSpot = this.getPosition();
String parSpot = par.getPosition();
while (this.seesSlot() & par.seesSlot())
{ if (this.seesCD() & par.seesCD())
{ this.moveOn();
par.moveOn();
}
if (this.seesCD() & ! par.seesCD())
this.moveOn();
if ( ! this.seesCD() & par.seesCD())
par.moveOn();
if ( ! this.seesCD() & ! par.seesCD())
{ this.moveOn();
par.moveOn();
}
}
boolean valueToReturn = ! this.seesSlot() & ! par.seesSlot();
this.backUpTo (thisSpot);
par.backUpTo (parSpot);
return valueToReturn;
}
Exercise 3.37*Revise the lastEmptySlot method to return the position of the next to- last empty slot. Return the initial position if the executor has less than two empty slots.
public String lastEmptySlot()
{ int count = 0;
String spot = this.getPosition();
String lastEmpty = spot; // in case no later slot is empty
while (this.seesSlot())
{ backup();// move to front of sequence
}
moveOn();// move to first slot
while (this.seesSlot())
{ if (!this.seesCD())
count++;// count number of empty slots
moveOn();
}
if (count < 2)
return lastEmpty;
else {
this.backUp();
while (this.seesSlot())
{ if ( ! this.seesCD()){
lastEmpty = this.getPosition();
break;
}
this.backUp();
}
while (this.seesSlot()){
if ( ! this.seesCD()){
lastEmpty = this.getPosition();
break;
}
this.backUp();
}
return lastEmpty;
}
} //======
Exercise 3.38*Rewrite the lastEmptySlot method to have the executor go directly to the end of the sequence and then find the last empty slot as it comes back towards the starting position.
public String lastEmptySlot()
{ String spot = this.getPosition();
String lastEmpty = spot; // in case no other slots are empty
while (this.seesSlot()) // go to the end of the sequence
this.moveOn();
backUp(); // back up to the last slot
while ( this.seesCD()) // while it sees a cd..
backUp(); // back up until it comes to an empty slot
lastEmpty = this.getPosition(); // record the position of the empty slot
this.backUpTo (spot); // back up to the initial start
return lastEmpty; // return the value of lastEmpty
} //======
Unit 9 - Assignments - 10 Marks
Exercise 4.1*Write an application program that asks the user for two strings of characters and then tells the user whether they are equal to each other (print "equal" or "different"). But tell the user "Stop fooling around" if either entry is null.
import javax.swing.JOptionPane;
public class Exercise41
{
public static void main(String args[])
{
String S1, S2;
S1 JOptionPane.showInputDialog(null,"Enter text", "Exercise 4.1", JOptionPane.INFORMATION_MESSAGE);
S2 JOptionPane.showInputDialog(null,"Enter text", "Exercise 4.1", JOptionPane.INFORMATION_MESSAGE);
if(S1= null || S2= null)
JOptionPane.showMessageDialog(null, "Stop fooling around!", "Noo!", JOptionPane.ERROR_MESSAGE);
else
{
if(S1.equals(S2))
JOptionPane.showMessageDialog(null, "equal! :)");
else
JOptionPane.showMessageDialog(null, "different! :(");
}
} // End of method
}
Exercise 4.2*Draw the UML class diagram for Listing 4.2.
Unit 10 - Assignments - 20 Marks
Exercise 4.5*:Revise the BasicGame logic so that the user who takes more than three guesses to get it right will never succeed in guessing the right answer. Hint: See the preceding exercise (4.4)

public void playOneGame()

{

x = 0;

askUsersFirstChoice();

while (shouldContinue() || x >= 3)

{

showUpdatedStatus();

askUsersNextChoice();

}

showFinalStatus();

}

Exercise 4.6*Explain the difference between an instance variable and a local variable.
An instance variable is a variable that belongs to a class and can be called on by all methods in said class.
Local variables are variables that belong to a specific method and thus can only be called upon by that method unless otherwise modified.


Exercise 4.17*Write a Time method public Time subtract (Time that): The executor returns a new Time object that is itself minus the parameter, e.g., 0720 subtract 1430 is 1650. If the difference is negative, add an extra 24 hours.
public Time subtract (Time that)
{
int hr;
int min;
hr = (this.itsTimeHour - that.itsTimeHour);
min = (this.itsTimeMins - that.itsTimeMins);
if ( min < 0)
{
min = (min + 60);
hr--;
}
if (hr < 0)
hr = (hr + 24);
Time difference = new Time ( hr, min);
return difference;
}
Exercise 4.18*If you wanted Time objects to have a third attribute, the name of the day of the week, then (a) What instance variable declaration would you add? (b) What change would you make in the constructor? (c) What instance method would you have that tells the caller the object's day of the week? Write and compile the revised class.
I added instance variable private int itsDay and made it so that in the constructor the day was the first int entry and that itsDay got its value from the int day in Time (int day, int hour, int min). I also added the instance method dayString() to class Time. I designed it so that which ever interger you enter into the day parameter of a new time object would be assigned a day name. The system goes 1 = Sunday and up to 7 = Saturday. If the number entered into the day parameter is large then 7 or lower then 1 it lowers or raises by increments of 7 until it fits one of the day numbers 1-7.
public String dayString()
{
while (itsDay <= 0)
itsDay = (itsDay + 7);
while (itsDay > 7)
itsDay = (itsDay - 7);
if( itsDay == 1)
return "Sunday";
if( itsDay == 2)
return "Monday";
if( itsDay == 3)
return "Tuesday";
if( itsDay == 4)
return "Wednesday";
if( itsDay == 5)
return "Thursday";
if( itsDay == 6)
return "Friday";
if( itsDay == 7)
return "Saturday";
return "No such date";
}
Exercise 4.19*Revise the Time constructor to properly adjust for itsMin larger than 59, adding to itsHour as needed. Then repeatedly add or subtract 24 from itsHour until the value is in the range 0 to 23 (discard the excess; we do not care what day it is).
//This has the revision made to it form exercise 4.19 and int day added from 4.18
public Time (int day, int hour, int min)
{
super();
itsDay = day;
itsTimeHour = hour;
for (itsTimeMins = min; itsTimeMins < 0; itsTimeMins = itsTimeMins + 60)
itsTimeHour--;
for (itsTimeMins = min; itsTimeMins >= 60; itsTimeMins = itsTimeMins - 60)
itsTimeHour++;
for (itsTimeHour = hour; itsTimeHour >= 24; itsTimeHour = itsTimeHour - 24)
// do nothing here;
for (itsTimeHour = hour; itsTimeHour < 0; itsTimeHour = itsTimeHour + 24)
// do nothing here;
}
Exercise 4.20*Revise the Time constructor as stated in the preceding exercise, but do not have any looping statements anywhere in the constructor. Hint: Use the % operator.
public Time (int day, int hour, int min)
{
super();
itsDay = day;
itsTimeHour = hour;
itsTimeMins = min;
itsTimeHour = itsTimeHour + (itsTimeMins / 60);
itsTimeMins = itsTimeMins % 60;
if (itsTimeMins < 0)
{
itsTimeHour = itsTimeHour - 1;
itsTimeMins = itsTimeMins + 60;
}
itsTimeHour = itsTimeHouer % 24;
}
Unit 11 - Assignment - 25 Marks
Exercise 4.26*Write an application program that asks the user for two int values and then announces whether one evenly divides the other (using %).
import javax.swing.JOptionPane;
public class ExerciseFourTwentySix
{
public static void main (String[] args)
{
String numOne = JOptionPane.showInputDialog
("First number:");
String numTwo = JOptionPane.showInputDialog
("Second number:");
int num1 = Integer.parseInt (numOne);
int num2 = Integer.parseInt (numTwo);
int remainderFirst = num1 % num2;
int remainderSecond = num2 % num1;
if (remainderFirst == 0)
JOptionPane.showMessageDialog (null,
numTwo + " divides evenly into " + numOne);
if (remainderSecond == 0)
JOptionPane.showMessageDialog (null,
numOne + " divides evenly into " + numTwo);
if (remainderFirst != 0 & remainderSecond != 0)
JOptionPane.showMessageDialog (null,
"Neither number divides evenly into the other");
}
}
Exercise 4.27*Revise the GuessNumber game to say "you're hot" if within 2 of the right answer, "you're warm" if within 6 of the right answer, and "too high" or "too low" otherwise.
import javax.swing.JOptionPane;
public class GuessNumber extends BasicGame
{
private java.util.Random randy;
private int itsSecretNumber;
private int itsUsersNumber;
public GuessNumber()
{ super();
randy = new java.util.Random();
} //======
public void askUsersFirstChoice()
{ itsSecretNumber = 1 + randy.nextInt (100);
askUsersNextChoice();
} //======
public void askUsersNextChoice()
{ String s = JOptionPane.showInputDialog
("Guess my number from 1 to 100:");
if (s != null & ! s.equals (""))
itsUsersNumber = Integer.parseInt (s);
else
itsUsersNumber = -1; // just to have a value there
} //======
public boolean shouldContinue()
{ return itsUsersNumber != itsSecretNumber;
} //======
public void showUpdatedStatus()
{
int difference = itsUsersNumber - itsSecretNumber;
if (difference >= -2 & difference <= 2 & difference != 0)
JOptionPane.showMessageDialog (null, "You're hot!");
if ((difference >= -6 & difference <= -3) || (difference >= 3 & difference <= 6))
JOptionPane.showMessageDialog (null, "You're warm");
if (difference > 6)
JOptionPane.showMessageDialog (null, "Too high");
if (difference < -6)
JOptionPane.showMessageDialog (null, "Too low");
} //======
// inherited from BasicGame:
// playManyGames
// playOneGame
// showFinalStatus
}
Exercise 4.28*Revise the GuessNumber game to have the program lie one-third of the time that the guess is too high; it says it is too low. But it never lies about the guess being too low, nor does it lie twice in a row.
public void showUpdatedStatus()
{
if (itsUsersNumber > itsSecretNumber)
{
randy2 = new java.util.Random();
int lieNum = randy2.nextInt(3);
if (lieNum == 0 & lastAnswer.equals ("truth"))
{
JOptionPane.showMessageDialog (null, "Too low");
lastAnswer = "lie";
}
else
{
JOptionPane.showMessageDialog (null, "Too high");
lastAnswer = "truth";
}
}
else
{
JOptionPane.showMessageDialog (null, "Too low");
lastAnswer = "truth";
}
} //======
Exercise 4.29*Find the best strategy for getting the right answer in the fewest guesses for the revision of GuessNumber described in the preceding exercise.
The best way to guess the number in the fewest number of tries is:
Start by guessing 50
If too high, guess 25
If too low, guess 50 again to make sure it is too low
If too low again guess 75
If too high, guess 25
Repeat with new guesses, halfway between the known maximum and minimum, making sure any computer claim of “too low” is really too low by guessing the same number again.
Exercise 4.32*Write out the signature of each method called in Listings 1.10 and 1.11.

Listing 1.10

showUpdatedStatus()

Listing 1.11

CentigradeFrame (String)
fieldAction 1 (BabyField 1)
main (String[] args)
Exercise 4.33*Write out the full Time constructor with the heading public Time(int totalMinutes). Be sure to allow for negative inputs.
public Time (int totalMinutes) // constructor
{
super();
itsHour = 0;
itsMin = totalMinutes;
for (itsMin = itsMin; itsMin < 0; itsMin = itsMin + 60)
itsHour--;
for (itsMin = itsMin; itsMin > 60; itsMin = itsMin - 60)
itsHour++;
for (itsHour = itsHour; itsHour < 0; itsHour = itsHour + 24);
for (itsHour = itsHour; itsHour >= 24; itsHour = itsHour - 24);
} //======
Exercise 4.34**Write out the BigVic constructor that Listing 4.7 needs.
public BigVic() // constructor
{
super();
itsNumFilled = 0;
itsNumEmpty = 0;
String spot = this.getPosition();
while (this.seesSlot())
{
if (this.seesCD())
itsNumFilled++;
if ( ! this.seesCD())
itsNumEmpty++;
this.moveOn();
}
while ( ! spot.equals (this.getPosition()))
this.backUp();
} //======
Exercise 4.37*There are eight possible assignments of true and false to the boolean variables b, c, and d. Which assignments give !b & (c || !d) a different value from!(b || !c & d).
No assignments will give the two expressions different values.
Project:GuessThatNumber 15 marks
Write a subclass of BasicGame in which the computer asks the user to choose a whole number from 1 to 100, inclusive. The program then makes a number of guesses. After each guess, the user tells whether the guess is too high, too low, or exactly right. Once the computer "knows" what the correct number is, the computer tells the user the correct number and the number of guesses tried. Have the program ask the user after each game whether she wants to play again. Design the program so that it always guesses the correct answer by the seventh try at latest. Hint: Have two instance variables that keep track of the smallest and largest values that the guess could be (initially 1 and 100). Guess halfway between them. After each wrong guess, update these smallest and largest values appropriately.
import javax.swing.JOptionPane;
public class Guesser extends BasicGame
{
private int itsLowestNumber;
private int itsHighestNumber;
private int itsNumGuesses;
/** Constuctor **/
public Guesser()
{
super();
}
public void playOneGame()
{
instuctUser();
while (!guessNumber());
showFinalStatus();
}
public void instuctUser()
{
itsLowestNumber = 0;
itsNumGuesses = 0;
itsHighestNumber = 100;
JOptionPane.showMessageDialog( null,
"Think of a number from 1 to 100\nI will try to guess it.");
}
/** GuessNumber
* Returns true if user says guess is correct **/
public boolean guessNumber()
{
itsNumGuesses++;
int nextGuess = (itsHighestNumber - itsLowestNumber) / 2 + itsLowestNumber;
boolean valueToReturn;
Object[] options = { "Too Low", "Too High", "Correct" };
int n = JOptionPane.showOptionDialog(null, nextGuess + "?",
"Guess", JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE, null,
options, options[0]);
if (n == 0)
{
itsLowestNumber = nextGuess;
valueToReturn = false;
}
else if (n == 1)
{
itsHighestNumber = nextGuess;
valueToReturn = false;
}
else
valueToReturn = true;
return valueToReturn;
}
public void showFinalStatus()
{
JOptionPane.showMessageDialog( null,
"It took me " + itsNumGuesses + " guesses");
}
// Inherits:
// playManyGames
}
Unit 12 - Assignment - 25 Marks
Exercise 5.4*Write a method public static int gcd (int one, int two) for MathOp: It returns the greatest common positive divisor of its two int parameters. Hint: If either is negative, multiply it by -1; then repeatedly replace the larger by the remainder from dividing the larger by the smaller until one goes evenly into the other, in which case that one will be the greatest common divisor. What do you do if either is zero?

public static int gcd(int one, int two)

{

// make sure that neither one or two are negative

if ( one < 0 )

one = one * -1;

if ( two < 0 )

two = two * -1;

// make sure that one is the higher than two

if (one < two)

{

two = one + two;

one = two - one;

two = two - one;

}

// find the greatest common factor

while ( two != 0 )

{

int oneTemp = two;

two = one % two;

one = oneTemp;

}

return one;

}

Exercise 5.5*Under what circumstances can a call of a class method be polymorphic?
A call to a class method may be polymorphic if there is
another class with the same name that has a different
signature.
Exercise 5.6** Write a MathOp class method that finds the factorial of a given int value (e.g., 6! is 6 * 5 * 4 * 3 * 2 * 1). Watch out for negatives.
public static int factorial(int num)
{
if (num < 0)
return -1;
if (num == 0)
return 1;
else
return num * factorial(num-1);
}
Exercise 5.9*Change the Person class of Listing 5.2 so that any outside class can find out the smallest birth year of all the Persons who have been created so far. Use -1 for the answer if no Persons have yet been created.