Computer Science 15-100 (Sections S-V), Fall 2008
Homework 1
Due:  Mon 1-Sep-2008 at 11:59pm (email copy) and at Tuesday's class/recitation (identical physical copy)
(no late submissions accepted).


Read these instructions first!


  1. Do the following Exercises from Chapter 1 (pp 53-55):
    Exercises 1.16,  1.17,  1.18,  1.20
     
  2. Do the following Exercises from Chapter 2 (pp 106-108):
    Exercises 2.3,  2.6,  2.7,  2.8,  2.10,  2.11
     
  3. maxOf3
    Write the following method:
       public static int maxOf3(int i0, int i1, int i2)
    This method takes 3 integers and returns the value of the largest integer.  Here is a test method for you:
      public static void testMaxOf3() {
        System.out.print("Testing maxOf3... ");
        assert(maxOf3(1, 2, 3) == 3);  // 3rd is max
        assert(maxOf3(1, 3, 2) == 3);  // 2nd is max
        assert(maxOf3(3, 1, 2) == 3);  // 1st is max
        assert(maxOf3(1, 2, -3) == 2); // one negative
        assert(maxOf3(-1, -2, -3) == -1); // all negative
        assert(maxOf3(1, 1, 0) == 1);  // duplicate values
        System.out.println("Passed all tests!");
      }

    Hint #1:  test methods not only help you test your code, they can also help you understand the problem in the first place even before you write any code.  Thus, before writing your solution, study each assertion in the test method and be sure you understand why it must be true.

    Hint #2:  you should use Math.max here, though you cannot simply call Math.max(i0,i1,i2), as Math.max only works with two parameters.
     

  4. medianOf3
    Write the following method:
       public static int medianOf3(int i0, int i1, int i2)
    This method takes 3 integers and returns the value of the middle value of the 3.  Here is a test method for you:
      public static void testMedianOf3() {
        System.out.print("Testing medianOf3... ");
        assert(medianOf3(2, 1, 3) == 2); // 1st is median
        assert(medianOf3(1, 2, 3) == 2); // 2nd is median
        assert(medianOf3(1, 3, 2) == 2); // 3rd is median
        assert(medianOf3(1, 2, -3) == 1); // one negative
        assert(medianOf3(-1, -2, -3) == -2); // all negative
        assert(medianOf3(1, 1, 0) == 1); // duplicate values
        System.out.println("Passed all tests!");
      }

    Hint:  Think about how your previous solution might inform this problem...
     

  5. hundredsDigit
    Write the following method:
       public static int hundredsDigit(int i)
    This method takes one integer and returns the value of that number's hundreds digit.  Here is a test method for you:
      public static void testHundredsDigit() {
        System.out.print("Testing hundredsDigit... ");
        assert(hundredsDigit(100) == 1);
        assert(hundredsDigit(123) == 1);
        assert(hundredsDigit(1234) == 2);
        assert(hundredsDigit(-1234) == 2);
        assert(hundredsDigit(0) == 0);
        assert(hundredsDigit(12) == 0);
        assert(hundredsDigit(-12) == 0);
        System.out.println("Passed all tests!");
      }

    Hint:  The test method is very valuable here.  It shows that numbers less than 100 have a 0 as their hundreds digit.  It further shows how you should handle negative numbers.  Again, for this and all problems, carefully scrutinize the test methods that we provide (if and when we do so) to gain as deep an understanding of the problem as you can prior to writing any code.
     

  6. almostEqual
    Write the following method:
       public static boolean almostEqual(double d1, double d2)
    This method takes two doubles and returns true if the two doubles are "almost equal" (within 0.0001 of each other for our purposes) and false otherwise.  Here is a test method for you:
      public static void testAlmostEqual() {
        System.out.print("Testing almostEqual... ");
        assert(almostEqual(0, 0.0001/2)); // 0 and epsilon/2
        double epsilon = 0.0001;
        assert(almostEqual(0, epsilon/2)); // a small positive that is nearly 0!
        assert(!almostEqual(0, epsilon)); // this should "just" be false
        // use the example from the class notes
        double d1 = (29.0 / 7.0) * 7.0;
        double d2 = 29.0;
        assert(d1 != d2);
        assert(almostEqual(d1, d2));   // two very-nearly-equal values
        assert(almostEqual(-d1, -d2)); // and their negations
        System.out.println("Passed all tests!");
      }

    Hint #1:  Once again, the oh-so-helpful test method shows us that doubles that are exactly 0.0001 apart are not almost equal.  They must be strictly within that epsilon.

    Hint #2:
      We basically solved this in the class notes, but here we are placing that code in a method.  Why would we do that?
     

  7. distance
    Write the following method:
       public static double distance(double x0, double y0, double x1, double y1)
    This method takes four doubles, x0, y0, x1, and y1, and returns a double representing the distance from the point (x0,y0) to the point (x1,y1).  Here is a test method for you:
      public static void testDistance() {
        System.out.print("Testing distance... ");
        assert(almostEqual(distance(0,0,0,0), 0));
        assert(almostEqual(distance(0,0,1,0), 1));
        assert(almostEqual(distance(1,0,0,0), 1));
        assert(almostEqual(distance(0,0,1,1), Math.sqrt(2)));
        assert(almostEqual(distance(0,0,-1,1), Math.sqrt(2)));
        assert(almostEqual(distance(4,3,1,7), 5));
        System.out.println("Passed all tests!");
      }

    Hint #1:  Here is the distance formula: 

    Hint #2:  You may wish to use both Math.pow and Math.sqrt here.

    Hint #3:  This is not so much a hint as a thought question:  why do the test assertions use "almostEqual" rather than "=="?
     

  8. isRightTriangle
    Write the following method:
       public static boolean isRightTriangle(double x0, double y0,
                                             double x1, double y1,
                                             double x2, double y2)

    This method takes six doubles describing three points (x0, y0), (x1, y1), and (x2, y2), and returns true if the triangle connecting those points is a right triangle and false otherwise.  How do you do that?  First, find the distances of each side.  If we call those distances a, b, and c, where c is the largest side, then the triangle is a right triangle if and only if a2 + b2 = c2 (by the converse of the Pythagorean Theorem).

    Here is a test method for you:
      public static void testIsRightTriangle() {
        System.out.print("Testing isRightTriangle... ");
        assert(isRightTriangle(0,0,3,0,0,4)); // 3,4,5 triangle
        assert(isRightTriangle(0,0,-3,0,0,-4)); // another 3,4,5 triangle
        assert(!isRightTriangle(0,0,1,10,2,0)); // tall isosceles triangle
        assert(!isRightTriangle(0,0,0,0,0,0)); // all same points, not a triangle!
        double epsilon = 0.0001;
        assert(!isRightTriangle(epsilon/10,0,0,0,-epsilon/10,0)); // all nearly same points!
        assert(isRightTriangle(0, 0, epsilon, 0, 0, epsilon)); // "barely" a triangle!
        System.out.println("Passed all tests!");
      }

    Hint #1:  All the values are doubles, so be sure to use the appropriate test for equality.

    Hint #2:
      You may want to use some of the methods that you wrote above.  In general, reusing your own code is a Very Good Idea!

    Hint #3:  Again, scrutinize the test method.  It shows several subtle cases.  For example, if two (or more) of the three points are the same, or even just very nearly the same (or, more specifically, if the distance between them is "almostEqual" to zero), then you do not have a triangle, let alone a right triangle, so you should return false.
     

  9. Bonus/Optional:  quadrantOfIntersection
    Write the following method:
       public static int quadrantOfIntersection(double m1, double b1, double m2, double b2)
    This method takes four doubles representing the two lines y=m1*x+b1 and y=m2*x+b2 and returns an int value representing the quadrant where these two lines intersect.  You are guaranteed they do intersect and in just a single point, so you can ignore the case of parallel lines or the case of identical lines.  Specifically, your method should return a 1 if the lines intersect in the top-right quadrant, a 2 for the top-left, a 3 for the bottom-left, and a 4 for the bottom-right.  If the two lines intersect at (or "very nearly" at) the origin, you should return a 0.  Also, you should write your own test method for this problem:
       public static void testQuadrantOfIntersection()
    Be thoughtful about your test cases, trying to test all the different conditions that might arise.

    Hint:  You may wish to use trigonometry (Math.sin, Math.cos, Math.tan) to find the angle to the point of intersection, and then you can divide this appropriately to convert from an angle between 0 and 2pi (in radians) and the quadrant number.  Alternatively:  on only this problem, you may (for a small deduction) use an "if" statement.

    Note: You may make any reasonable assumption as to how to handle intersections lying precisely on the x or y axes.
     
  10. Bonus/Optional:  unitVolumePrismHeight
    Write the following method:
       public static double unitVolumePrismHeight(double x0, double y0,
                                                  double x1, double y1,
                                                  double x2, double y2)

    This method takes six doubles representing the points (x0, y0), (x1, y1), and (x2, y2).  These points form a triangle.  If you drag that triangle through the third dimension, you form a triangular prism, as such:

    As with a rectangular prism, the area of a triangular prism (at least a right triangular prism, which is what we will restrict ourselves to) is simply the area of its (triangular) base times its height.  This method returns the height required so that the given triangular prism will have a volume of 1.  If the given points do not form a triangle, the method should return -1.  Also, you should write your own test method for this problem:
       public static void testUnitVolumePrismHeight()
    Again, be thoughtful about your test cases, trying to test all the different conditions that might arise.

    Hint:  You may wish to use Heron's Formula here.

    Note:  Unlike the previous problem, here you may not use "if" statements, not even for partial credit (but you will receive some partial credit for solving everything except the non-triangle case).

Carpe diem!