CS 201 - Homework 1 - Java

Due: Wednesday 9/20 at 8am

This assignment consists of some warm-up exercises that we will do together in lab, and three programming problems. You may work on this homework in pairs of two or by yourself. If you work in a pair, all three problems must be done together, and only one person should upload the files. Be sure that both of your names appear in a comment at the top of each file!

When you are done, please upload your java files (Mortgage.java, FindPrincipal.java, and Shuffle.java) using the HW 1 submission page.

Don't forget to document your code (see Bailey, chapter 2). And of course, always put your name(s) in a comment at the top.


Lab exercises


Problem 1: Mortgage Payments

You're thinking of buying a house! You've decided to use Java to see what sort of monthly mortgage payments you can afford. There are three relevant parameters in determining a mortgage:

  1. The principal P, which is the cost of the house.
  2. The annual interest rate i, measured in percent.
  3. The number of years y in the mortgage, typically 30.

The monthly mortgage rate M can be calculated according to the following formula:

P * (i/1200)
1 - (1/(1 + (i/1200)))(12*y)

(Note that the interest parameter i should be a number in the range 0 to 100 rather than 0 to 1. That is, 7.25% is expressed as 7.25, not 0.0725.) For example, the monthly mortgage payment on a $250,000 house with 7% interest and a 30-year mortgage is $1663.26. After 30 years, the total mortgage payments amount to $598,772 -- over twice the listed cost of the house. This is how banks make money!

To solve this problem, you should implement the following methods:

Start by creating a new file Mortgage.java, then copy and paste the following into your editor to get started.

// Mortgage.java
// CS 201 HW 1 problem 1

public class Mortgage {

    // Below is a sample comment for the 'mortgage' method.
    // ALL your methods always need comments!
    // And don't forget to put a comment at the top of your file as well.

    // Calculates monthly mortgage from parameters:
    //   principal - the principal in dollars
    //   interest  - the interest in percent
    //   years     - the duration of the mortgage in years
    // Returns the monthly mortagage payment.
    public static double mortgage(double principal, double interest,
                                  double years) {

        // FILL IN

        return 0;  // just a placeholder
    }
        
    public static void print(double principal, double interest, double years) {

        // FILL IN
    }

    public static void main (String[] args) {

        // FILL IN

    }
}


Problem 2: It's the Principal of the Thing

The mortgage method in Problem 1 tells you the monthly mortgage given the principal, interest rate, and the number of years. But suppose instead you have determined the monthly mortgage M that best fits your budget and want to determine the principal P for the most expensive house you can afford for that mortgage (for a given interest rate and number of years).

One approach is to try to algebraically manipulate the formula from Problem 1 to express P as a function of M, interest, and the number of years. But you are rusty on your algebra, so you decide not to take that tack.

An alternate approach is to use the mortgage method from Problem 1 as a way of evaluating a sequence of guesses at the desired principal P. The principal P you seek is the one for which mortgage returns M. You can use the binary search idea from the HiLo game as a way of effectively guessing P. In particular, suppose you know that P is in the closed interval [lo, hi]. Then because mortgage is a monotonically increasing function, you can use the result of applying mortgage to the midpoint of lo and hi to narrow P to be in one-half of this interval. By successively halving the interval, you can quickly converge to a result P' whose mortgage M' is within one dollar of M. At that point, you can declare P' as the desired principal.

Implement this idea by filling in the missing parts of the following FindPrincipal class, which you should implement in a file FindPrincipal.java. (You can copy and paste the following into your editor.)

public class FindPrincipal {
              
    public static double find(double mortgage, double interest,
			      double years) {

	return findBetween(mortgage, interest, years, 
			   0, upperBound(mortgage, interest, years));
    }
              
    public static double findBetween(double mortgage, double interest, 
				     double years, double lo, double hi) {
	// FILL IN
    }
              
    public static double upperBound(double mortgage, double interest,
				    double years) {
	// FILL IN
    }
       
    public static void testFind(double m, double i, double y) {
	System.out.println("find(" + m + ", " + i + ", " + y + ") = "
			   + find(m, i, y));
    }

    public static void main(String [] args) {
	testFind(1200.00, 7.00, 30.0);
    }

}

The find method defers to findBetween to find a principal in the interval [0, u], where u is an upper bound on the desired principal P -- i.e., u is guaranteed to be greater than or equal to P. The find method should use binary search to converge to a principal P whose mortgage within one dollar of the mortgage parameter to findBetween. (Use Math.abs to calculate absolute values.) The upperBound method determines an upper bound u for P. It should implement the following strategy: starting with the principal 1, successively double it until reaching a principal Q whose mortgage is greater than the given mortgage limit. Q is clearly an upper bound for P.

The main method will test your code by determining the maximum house price that can be purchased for a $1200.00 per month mortgage in a 30-year mortgage at 7% interest.

Note: For this problem, you will need to compute the mortgage as in problem 1. Instead of copying the code from problem 1, you can simply call that method the following way:
    double m = Mortgage.mortgage(...);
Again, don't forget to document your code. You need your name at the top of the file, and all your functions need a comment explaining what they do.


Problem 3: Perfect Shuffles

The problem

Let A be an array of integers with an even number L of elements. A perfect shuffle of A is an operation that permutes the elements of the array by interleaving the elements of the segment A[0..(L/2)-1] with the elements of the segment A[(L/2)..L-1]. For concreteness, consider a length 8 identity array. (An identity array is an array in which the slot with index i holds the integer i.):

[0, 1, 2, 3, 4, 5, 6, 7]

The result of a perfect shuffle on the above array is:

[0, 4, 1, 5, 2, 6, 3, 7]

A second perfect shuffle gives:

[0, 2, 4, 6, 1, 3, 5, 7]

In the case of L=8 a third perfect shuffle results in the original array:

[0, 1, 2, 3, 4, 5, 6, 7]

Let us call the number of perfect shuffles it takes to return an array to its original state the shuffle period of the array. So the shuffle period for L=8 is 3. Your goal in the problem is to write a method printShufflePeriods that prints each even array length and its associated shuffle period within a given interval of array lengths:

public static void printShufflePeriods(int lo, int hi)
Assume lo and hi are even integers. For each even integer k in the interval [lo, hi], print a line whose contents is shufflePeriod(k)=p, where p is the shuffle period for an array of length k.

As part of your solution, you should implement the following auxiliary methods:

public static int[] identity(int L)
Return an identity array with length L.

public static boolean isIdentity(int[] A)
Return true if A is an identity array, and false otherwise.

public static int[] perfectShuffle(int[] A)
Return a new array whose elements are the perfect shuffle of the elements of A. The array A should not be modified by this operation. Assume that A has even length.

public static int shufflePeriod(int L)
Return the shuffle period of an array with length L. Assume that L is even.

To help you write your program, you are provided with a skeleton file Shuffle.java, which you should save in your hw1 folder (use "save as", and select text mode). The Shuffle class includes skeletons for all the methods mentioned above, as well as a main method that tests your program by printing out the shuffle periods for all even array lengths in the range [2, 100]. The Shuffle class also includes a method for converting an integer array to a string called intArrayToString, which is handy for debugging your implementations of identity and perfectShuffle.

And one more time, don't forget to document your code. You can use the above text as comments for the functions, or you can write your own comments. Always put your name at the top of the file. If you work in a pair, be sure to list both names.