Solution #3

Flow control

Section 3.1 (warmup)

3.1.1

1.       Prints all the divisors of a positive number larger than 2.

2.       Variables:

a.       n: the number to find the divisors of. New name: number.

b.      c: the current candidate to be the numberís divisor. New name: currentDivisor.

3.       Improvements:

a.       Loop only until n/2.

3.1.2

1.       Reverses a String line.

2.       Variables:

a.       is: the input scanner. New name: inputScanner.

b.      l: the input line. New name: inputLine.

3.       Improvements:

a.       There can be no solution that is more time efficient than the original code. If the issue bothered you through the nights, if you Googled it, asked friends and read about reversing a String, then you most probably understand now all the issues around effective String reversing. This is good.

b.      Of course, a fast way to code it would be using String.reverse(), but thatís more efficient only to the coders, not in algorithm efficiency terms.

3.1.3

1.       The algorithm calculates a*b for non-negative a and b.

2.       Variables:

a.       a: the first number. New name: multiplicand.

b.      b: the second number. New name: multiplier.

3.       Improvements:

a.       Print a*b

3.1.4

1.       The algorithm prints all the prime numbers between 2 and 100.

2.       Variables:

a.       cn: the current candidate of a prime number. New name: primeNumber.

b.      ip: a flag, indicating whether the number is prime or not. New name: isPrime.

c.       pn: a current divisor of cn. If such divisor exists, the number is not prime. New name: currentDivisor

3.       improvements:

a.       The outer loop should skip all even numbers by replacing cn++ with cn += 2.

b.      The internal loop should run only until the square root of cn.

Section 3.2 (TextEncryption.java)

Without bonus

/**

†* This class encrypts text.

†*

†* @author Boaz Kantor

†*/

public class TextEncryption {

†††††

††††† /**

††††† †* This program takes a given String, source & destination characters, and

††††† †* encrypts the String by replacing each occurrence of the source character

††††† †* with the target character.

††††† †* This is a case sensitive version.

††††† †* @param args unused

††††† †*/

††††† public static void main(String[] args) {

†††††††††††

††††††††††† // local variables

††††††††††† char replace = 'o';

††††††††††† char replaceWith = '*';

††††††††††† String originalSentence = "The quick brown fox jumps over the lazy dog";

††††† ††††† String newSentence = "";

†††††††††††

††††††††††† // iterate through all the sentence characters

††††††††††† for (int currChar = 0; currChar < originalSentence.length(); ++currChar) {

†††††††††††††††††

††††††††††††††††† // case insensitive comparison

††††††††††††††††† if (originalSentence.charAt(currChar) == replace) {†† // itís acceptable to keep the char in a variable

†††††††††††††††††††††††

††††††††††††††††††††††† // the character fits, add to the new sentence the encrypted char

††††††††††††††††††††††† newSentence += replaceWith;

††††††††††††††††† } else {

†††††††††††††††††††††††

††††††††††††††††††††††† // the character doesn't fit, just copy it as is to the target String

††††††††††††††††††††††† newSentence += originalSentence.charAt(currChar);

††††††††††††††††† }

††††††††††† }

†††††††††††

††††††††††† // print the encryption output

††††††††††† System.out.println("Original sentence: " + originalSentence);

††††††††††† System.out.println("Encrypted sentence: " + newSentence);

††††† }

}

With bonus

/**

†* This class encrypts text.

†*

†* @author Boaz Kantor

†*/

public class TextEncryption {

†††††

††††† /**

††††† †* This program takes a given String, source & destination characters, and

††††† †* encrypts the String by replacing each occurrence of the source character

††††† †* with the target character.

††††† †* This is a case insensitive version.

††††† †* @param args unused

††††† †*/

††††† public static void main(String[] args) {

†††††††††††

††††††††††† // local variables

††††††††††† char replace = 'o';

††††††††††† char replaceWith = '*';

††††††††††† String originalSentence = "The quick brown fox jumps over the lazy dog";

††††††††††† String newSentence = "";

††††††††††† char smallReplace = replace;† // this is the small version of the char

††††††††††† char capitalReplace = replace;††††† // this is the capital version

†††††††††††

††††††††††† // make sure we keep both small and capital versions of the character

††††††††††† if (replace >= 'a' && replace <= 'z') {

†††††††††††††††††

††††††††††††††††† // the source character is small, set the capital one

††††††††††††††††† capitalReplace = (char)(replace - ('a' - 'A'));

††††††††††† } else {

†††††††††††††††††

††††††††††††††††† // the source character is capital, set the small one

††††††††††††††††† smallReplace = (char)(replace + ('a' - 'A'));

††††††††††† }

†††††††††††

††††††††††† // iterate through all the sentence characters

††††††††††† for (int currChar = 0; currChar < originalSentence.length(); ++currChar) {

†††††††††††††††††

††††††††††††††††† // case insensitive comparison

††††††††††††††††† if (originalSentence.charAt(currChar) == smallReplace ||

††††††††††††††††††††††††††††† originalSentence.charAt(currChar) == capitalReplace) {

†††††††††††††††††††††††

††††††††††††††††††††††† // the character fits, add to the new sentence the encrypted char

††††††††††††††††††††††† newSentence += replaceWith;

††††††††††††††††† } else {

†††††††††††††††††††††††

††††††††††††††††††††††† // the character doesn't fit, just copy it as is to the target String

††††††††††††††††††††††† newSentence += originalSentence.charAt(currChar);

††††††††††††††††† }

††††††††††† }

†††††††††††

††††††††††† // print the encryption output

††††††††††† System.out.println("Original sentence: " + originalSentence);

††††††††††† System.out.println("Encrypted sentence: " + newSentence);

††††† }

}

Section 3.2 (TurtlePolygons.java)

Without bonus

/**

†* This class is intended to practice loops with visible results using the turtle.

†* The turtle in the program draws polygons of different sides.

†* Each polygon with X sides is drawn inside (smaller than) the polygon

†* with X+1 sides.

†*

†* @author Boaz Kantor

†*/

public class TurtlePolygons {

 

††††† /**

††††† †* The program runs here. See the class documentation for details.

††††† †* @param args unused

††††† †*/

††††† public static void main(String[] args) {

 

††††††††††† // constants

††††††††††† final int MAXIMUM_SIDES = 15;

††††††††††† final int MINIMUM_SIDES = 3;

††††††††††† final double FULL_CIRCLE = 360;

††††††††††† final int RIGHT_ANGLE = 90;

††††††††††† final double BASIC_SIDE_LENGTH = 50;

††††††††††† final double SIDE_LENGTH_FACTOR = 50;

 

††††††††††† // local variables

††††††††††† double sideLength = BASIC_SIDE_LENGTH;

††††††††††† double angle = 0;

 

††††††††††† // instantiate and prepare our turtle

††††††††††† Turtle turtle = new Turtle();

††††††††††† turtle.tailDown();

††††††††††† turtle.turnLeft(RIGHT_ANGLE);

†††††††††††

†††††††††††

††††††††††† // each iteration draws an entire polygon

††††††††††† for (int sides = MINIMUM_SIDES; sides <= MAXIMUM_SIDES; sides++) {

 

††††††††††††††††† // calculate polygon-specific metrics

††††††††††††††††† sideLength += SIDE_LENGTH_FACTOR;

††††††††††††††††† angle = FULL_CIRCLE / sides;

†††††††††††††††††

††††††††††††††††† // draw the polygon. each iteration draws one side

††††††††††††††††† for (int currSide = 0; currSide < sides; ++currSide) {

††††††††††††††††††††††† turtle.moveForward(sideLength);

††††††††††††††††††††††† turtle.setAngle(turtle.getAngle() - angle); // use this for

††††††††††††††††††††††††††††††††††† ††††† ††††††††††††††††††††††† // better accuracy

††††††††††††††††† }

 

††††††††††† }

†††††††††††

††††††††††† // yeah, that's important too.

††††††††††† turtle.hide();

††††† }

}

With bonus

/**

†* This class is intended to practice loops with visible results using the turtle.

†* The turtle in the program draws polygons of different sides.

†* Each polygon with X sides is drawn inside (smaller than) the polygon

†* with X+1 sides.

†*

†* @author Boaz Kantor

†*/

public class TurtlePolygons {

 

††††† /**

††††† †* The program runs here. See the class documentation for details.

††††† †* @param args unused

††††† †*/

††††† public static void main(String[] args) {

 

††††††††††† // constants

††††††††††† final int MAXIMUM_SIDES = 35;

††††††††††† final int MINIMUM_SIDES = 3;

††††††††††† final double FULL_CIRCLE = 360;

††††††††††† final int RIGHT_ANGLE = 90;

††††††††††† final double BASIC_SIDE_LENGTH = 50;

††††††††††† /** The following constants are needed only for the bonus */

††††††††††† final double MAX_HEIGHT = 600;

††††††††††† final double MIN_HEIGHT = 200;

††††††††††† final double HEIGHT_DIFF = (MAX_HEIGHT-MIN_HEIGHT)/

††††††††††††††††††††††††††††††††††††††††††††††††††††† (MAXIMUM_SIDES - MINIMUM_SIDES);

 

††††††††††† // instantiate and prepare our turtle

††††††††††† Turtle turtle = new Turtle();

††††††††††† turtle.tailDown();

††††††††††† turtle.turnLeft(RIGHT_ANGLE);

†††††††††††

††††††††††† /** This is needed only for the bonus */

††††††††††† double factor = Math.sqrt(3)/2;

†††††††††††

††††††††††† // each iteration draws an entire polygon

††††††††††† for (int sides = MINIMUM_SIDES; sides <= MAXIMUM_SIDES; sides++) {

 

††††††††††††††††† // calculate polygon-specific metrics

††††††††††††††††† double height = MIN_HEIGHT + (HEIGHT_DIFF * (sides-MINIMUM_SIDES));

††††††††††††††††† double trianglesInHeight = sides / 2.0;

††††††††††††††††† double sideLength = height / (factor * trianglesInHeight);

††††††††††††††††† double angle = FULL_CIRCLE / sides;

†††††††††††††††††

††††††††††††††††† // handle square and triangle separately

††††††††††††††††† // all the literals here should have been declared as constants.

††††††††††††††††† if (sides < 5) {

††††††††††††††††††††††† if (sides == 3) {

††††††††††††††††††††††††††††† sideLength = 50;

††††††††††††††††††††††† } else {

††††††††††††††††††††††††††††† sideLength = 100;

††††††††††††††††††††††† }

††††††††††††††††† }

 

††††††††††††††††† // draw the polygon. each iteration draws one side

††††††††††††††††† for (int currSide = 0; currSide < sides; ++currSide) {

††††††††††††††††††††††† turtle.moveForward(sideLength);

††††††††††††††††††††††† turtle.setAngle(turtle.getAngle() - angle); // use this for

††††††††††††††††††††††††††††††††††††††††††††††††††††††††††† ††††† // better accuracy

††††††††††††††††† }

 

††††††††††† }

†††††††††††

††††††††††† // yeah, that's important too.

††††††††††† turtle.hide();

††††† }

 

}

Section 3.4 (TheMillionShekelDrop.java)

import java.util.Scanner;

import McqTrivia.Questionnaire;

 

/**

†* The Million Shekel Drop program is based on the UK show

†* "The Million Dollar Pound Drop".

†* The player is given 1,000,000 Shekels in cash at the beginning.

†* From now on, the player is asked 8 questions and given 4 answers, only one

†* of which is correct.

†* The player has to bet on an answer, or split his bet on several answers.

†* When the bet is made, the correct answer is checked, and then 2 things happen:

†* The cash left on incorrect answers is dropped (and lost).

†* The cash on the correct answer is given back to the player.

†* At any stage, if the player is left with no cash, they lose the game and go home.

†* After 8 questions, the player can go home with the amount of cash left in

†* their hands.

†*

†* @author Boaz Kantor

†*/

public class TheMillionShekelDrop {

†††††

††††† /**

††††† †* This method runs the entire game.

††††† †* See the class documentation for game details.

††††† †* @param args unused

††††† †*/

††††† public static void main(String[] args) {

††††††††††† final int INITIAL_CASH = 1000000;

††††††††††† final String MCQ_FILENAME = "mcq.txt";

††††††††††† final int NUMBER_OF_QUESTIONS_TO_WIN = 8;

††††††††††† final int NUMBER_OF_ANSWER_CHOICES = 4;

†††††††††††

††††††††††† // create and initialize the game object

††††††††††† Questionnaire game = new Questionnaire();

††††††††††† game.init(MCQ_FILENAME);

†††††††††††

††††††††††† // some useful variables

††††††††††† int cash = INITIAL_CASH;

††††††††††† Scanner inputScanner = new Scanner(System.in);

 

††††††††††† // printing some welcoming messages

††††††††††† System.out.println("The Million Shekel Drop!");

††††††††††† System.out.println("You have " + cash + " shekels.");

††††††††††† System.out.println("The cash that you have at hand after " +

††††††††††††††††††††††† NUMBER_OF_QUESTIONS_TO_WIN + " consecutive " +

††††††††††††††††††††††† "correct answers is yours!");

†††††††††††

††††††††††† // run the game for 8 questions or until cash is over

††††††††††† for (int currQuestion = 0;

††††††††††††††††††††††† currQuestion < NUMBER_OF_QUESTIONS_TO_WIN && cash > 0;

††††††††††††††††††††††† currQuestion++) {

†††††††††††††††††

††††††††††††††††† // make sure the player understands where they stand

††††††††††††††††† System.out.println("You now have " + cash + " shekels.");

†††††††††††††††††

††††††††††††††††† // if the MCQ file has too few questions, end the game

††††††††††††††††† if (!game.hasMoreQuestions()) {

††††††††††††††††††††††† System.out.println("Sorry, we have no more questions left.");

††††††††††††††††††††††† System.out.println("You can leave with your " + cash + " shekels.");

††††††††††††††††††††††† break;

††††††††††††††††† }

†††††††††††††††††

††††††††††††††††† // start handling the next question

††††††††††††††††† System.out.println("Next question: ");

††††††††††††††††† game.printNextRandomQuestion();

††††††††††††††††† int correctAnswer = game.getCorrectAnswer();

††††††††††††††††† int cashWon = 0;

†††††††††††††††††

††††††††††††††††† // handle each answer separately

††††††††††††††††† for (int currAnswer = 0;

††††††††††††††††††††††††††††† currAnswer < NUMBER_OF_ANSWER_CHOICES && cash > 0;

††††††††††††††††††††††††††††† currAnswer++) {

†††††††††††††††††††††††

††††††††††††††††††††††† // let the player bet on the current answer

††††††††††††††††††††††† System.out.print("How much money would do you put on answer " +

††††††††††††††††††††††††††††††††††† (char)('A' + currAnswer) + " (0-");

††††††††††††††††††††††† System.out.print(cash + "): ");

††††††††††††††††††††††† int userBet = 0;

 

††††††††††††††††††††††† // get the player bet for the current answer

††††††††††††††††††††††† if (currAnswer == NUMBER_OF_ANSWER_CHOICES - 1) {

†††††††††††††††††††††††††††††

††††††††††††††††††††††††††††† // the player must bet on all their money in each question

††††††††††††††††††††††††††††† userBet = cash;

††††††††††††††††††††††††††††† System.out.println(userBet + " (automatic)");

††††††††††††††††††††††† } else {

†††††††††††††††††††††††††††††

††††††††††††††††††††††††††††† // the player can choose how much to bet on this answer

††††††††††††††††††††††††††††† userBet = inputScanner.nextInt();

 

††††††††††††††††††††††††††††† // verify that the bet is valid

††††††††††††††††††††††††††††† while (userBet < 0 || userBet > cash) {

††††††††††††††††††††††††††††††††††† System.out.println("You don't have that amount of cash.");

††††††††††††††††††††††††††††††††††† System.out.print("How much money would do you put on answer " +

††††††††††††††††††††††††††††††††††††††††††††††† (char)('A' + currAnswer) + " (0-");

††††††††††††††††††††††††††††††††††† System.out.print(cash + "): ");

††††††††††††††††††††††††††††††††††† userBet = inputScanner.nextInt();

††††††††††††††††††††††††††††† }

††††††††††††††††††††††† }

 

††††††††††††††††††††††† // we're only interested on the correct answer

††††††††††††††††††††††† if (correctAnswer == currAnswer) {

††††††††††††††††††††††††††††† cashWon = userBet;

††††††††††††††††††††††† }

††††††††††††††††††††††† cash -= userBet;

††††††††††††††††† }

†††††††††††††††††

††††††††††††††††† // no more bets! let's check the correct answer..

††††††††††††††††† System.out.println("The correct answer is: " +

††††††††††††††††††††††††††††† (char)('A' + correctAnswer));

††††††††††††††††† cash = cashWon;

†††††††††††††††††

††††††††††††††††† // check if the player has lost the game

††††††††††††††††† if (cash == 0) {

††††††††††††††††††††††† System.out.println("You have no more cash left. You lose.");

††††††††††††††††† }

††††††††††† }

†††††††††††

††††††††††† // game over, print a goodbye message

††††††††††† System.out.println("You are going home with " + cash + " shekels.");

††††††††††† System.out.println("Bye!");

††††† }

}