Computer Science 15-100, Spring 2009
Homework 2 Practice
Due:  Never.  This is not assigned work.


Note:  You may not use Java concepts we have not yet covered, including loops (do/while/for), conditionals ("if" statements or tertiary operators (?:)), arrays, or methods from any classes in java.util.* (unless explicitly indicated, such as Scanner) to solve these problems.  While they may be helpful, every problem here is solvable without them.


  1. xor
  2. modlessRemainder
  3. nearestBusStop
  4. isLegalTriangle
  5. xIntercept
  6. xInterceptOfParabola
  7. nthFibonacci
  8. dayOfWeek
  9. maxOf3
  10. medianOf3
  11. hundredsDigit
  12. almostEqual
  13. distance
  14. isRightTriangle

  1. xor

    class MyCode {

      // This method takes two booleans and returns true if
      // exactly one, but not both, of them is true.  If both
      // booleans are true, or both are false, this returns false.
      // This method is traditionally named "xor", where the "x" stands
      // for "exclusive", since we exclude the true-true case.

      public static boolean xor(boolean b1, boolean b2) {
        return true;  // replace this with your answer!
      }

      public static void testXor() {
        System.out.print("Testing xor... ");
        assert(!xor(true, true));
        assert(xor(true, false));
        assert(xor(false, true));
        assert(!xor(false, false));
        System.out.println("Passed all tests!");
      }

      public static void main(String[] args) {
        testXor();
      }
    }
     
  2. modlessRemainder
    class MyCode {
    
      // This method takes two positive numbers, x and y, and returns
      // the remainder when you divide x by y.
      // Of course, this is just (x % y), but the trick is that here
      // you are not allowed to use the % operator.
      // This can be done using the other arithmetic operators (+, -, *, /).
      // You may ignore the cases where x is negative or y is zero or negative.
    
      public static int modlessRemainder(int x, int y) {
        return 42; // replace this with your answer!
      }
    
      public static void testModlessRemainder() {
        System.out.print("Testing modlessRemainder... ");
        assert(modlessRemainder(0,3) == 0);
        assert(modlessRemainder(1,3) == 1);
        assert(modlessRemainder(2,3) == 2);
        assert(modlessRemainder(3,3) == 0);
        assert(modlessRemainder(4,3) == 1);
        assert(modlessRemainder(5,3) == 2);
        assert(modlessRemainder(6,3) == 0);
        assert(modlessRemainder(7,3) == 1);
        assert(modlessRemainder(1437, 82) == (1437 % 82));
        System.out.println("Passed all tests!");
      }
    
      public static void main(String[] args) {
        testModlessRemainder();
      }
    }
  3. nearestBusStop
    class MyCode {
    
      // This method takes a street number (which you may assume is positive),
      // and returns the street number of the nearest bus stop, where buses
      // stop on streets that are multiples of 8 (8th, 16th, 24th, etc).
      // So it behaves as such:
      //   nearestBusStop(11) returns 8
      //   nearestBusStop(13) returns 16
      // But what about 12th street?  It is equally far from 8th and 16th
      // streets, but riders generally head towards town (0th street), and
      // so they prefer the lower bus stop.  Hence:
      //   nearestBusStop(12) returns 8
      // You can assume there is a bus stop on 0th street, and again you
      // can ignore the case where the street is negative).
    
      // Remember: do not use conditionals, loops, arrays, etc.
      // This can be done (in one line of code!) using only what we
      // have covered Week #1's notes (in fact, using just addition,
      // division and multiplication of integers).
    
      public static int nearestBusStop(int street) {
        return 42; // replace this with your answer!
      }
    
      public static void testNearestBusStop() {
        System.out.print("Testing nearestBusStop... ");
        assert(nearestBusStop(0) == 0);
        assert(nearestBusStop(4) == 0);
        assert(nearestBusStop(5) == 8);
        assert(nearestBusStop(8) == 8);
        assert(nearestBusStop(11) == 8);
        assert(nearestBusStop(12) == 8);
        assert(nearestBusStop(13) == 16);
        System.out.println("Passed all tests!");
      }
    
      public static void main(String[] args) {
        testNearestBusStop();
      }
    }
  4. isLegalTriangle
    class MyCode {
    
      // This method takes three ints representing the lengths of the sides
      // of a triangle, and returns true if such a triangle exists and false
      // otherwise.  Note from the triangle inequality that the sum of each
      // two sides must be greater than the third side, and further note that
      // all sides of a legal triangle must be positive.
    
      public static boolean isLegalTriangle(int side1, int side2, int side3) {
        return true; // replace this with your answer!
      }
    
      public static void testIsLegalTriangle() {
        System.out.print("Testing isLegalTriangle... ");
        assert(isLegalTriangle(3, 4, 5));
        assert(isLegalTriangle(5, 4, 3));
        assert(isLegalTriangle(3, 5, 4));
        assert(!isLegalTriangle(3, 4, 7));
        assert(!isLegalTriangle(7, 4, 3));
        assert(!isLegalTriangle(3, 7, 4));
        assert(!isLegalTriangle(5, -3, 1));
        assert(!isLegalTriangle(-3, -4, -5));
        System.out.println("Passed all tests!");
      }
    
      public static void main(String[] args) {
        testIsLegalTriangle();
      }
    }
  5. xIntercept
    class MyCode {
    
      // This method takes 2 doubles representing the line y=mx+b,
      // and returns the value of the x-intercept.  You are assured
      // that the line has an x-intercept.
    
      public static double xIntercept(double m, double b) {
        return 42.0; // replace this with your answer!
      }
    
      public static void testXIntercept() {
        System.out.print("Testing xIntercept... ");
        assert(almostEqual(xIntercept(3,0), 0)); // y=3x, x-int at x=0
        assert(almostEqual(xIntercept(2,-4), 2)); // y=2x-4, x-int at x=2
        assert(almostEqual(xIntercept(3,-4), 1.3333333)); // y=3x-4, x-int at x=4/3=1.333...
        System.out.println("Passed all tests!");
      }
    
      public static boolean almostEqual(double d1, double d2) {
        double epsilon = 0.0001;
        return (Math.abs(d1 - d2) < epsilon);
      }
    
      public static void main(String[] args) {
        testXIntercept();
      }
    }
  6. xInterceptOfParabola
    class MyCode {
    
      // This method takes 3 doubles representing the parabola y=ax^2+bx+c,
      // and returns the value of the SMALLER x-intercept (using the quadratic
      // formula).  You are assured the line has at least one x-intercept.
    
      public static double xInterceptOfParabola(double a, double b, double c) {
        return 42.0; // replace this with your answer!
      }
    
      public static void testXInterceptOfParabola() {
        System.out.print("Testing xInterceptOfParabola... ");
        assert(almostEqual(xInterceptOfParabola(1,0,0), 0));  // y = x^2 has a zero at x=0
        assert(almostEqual(xInterceptOfParabola(1,0,-4), -2)); // y = x^2-4 has a zero at x=-2
        assert(almostEqual(xInterceptOfParabola(4,0,-4), -1)); // y = 4^2-4 has a zero at x=-1
        System.out.println("Passed all tests!");
      }
    
      public static boolean almostEqual(double d1, double d2) {
        double epsilon = 0.0001;
        return (Math.abs(d1 - d2) < epsilon);
      }
    
      public static void main(String[] args) {
        testXInterceptOfParabola();
      }
    }
  7. nthFibonacci
    class MyCode {
    
      // This method takes an int n and returns the nth Fibonacci number.
      // The Fibonacci numbers are 1, 1, 2, 3, 5, 8, 13, 21, 34, ....
      // As you can see, each number is the sum of the previous two.
      // From the great website mathforum.org, we see that the formula
      // for the nth Fibonacci number is:
      //    phi^(n+1) / sqrt(5)    -  (1-phi)^(n+1) / sqrt(5)
      // where phi is the Golden Ratio:
      //    phi = (1+sqrt(5))/2
      // Due to roundoff error of doubles, you may need to round the result,
      // which can be done by addition and casting (truncation), or
      // by a suitable Math method (though we've not covered that yet!).
    
      public static int nthFibonacci(int n) {
        return 42; // replace this with your answer!
      }
    
      public static void testNthFibonacci() {
        System.out.print("Testing nthFibonacci... ");
        assert(nthFibonacci(0) == 1);
        assert(nthFibonacci(1) == 1);
        assert(nthFibonacci(2) == 2);
        assert(nthFibonacci(3) == 3);
        assert(nthFibonacci(4) == 5);
        assert(nthFibonacci(5) == 8);
        assert(nthFibonacci(6) == 13);
        assert(nthFibonacci(7) == 21);
        assert(nthFibonacci(8) == 34);
        System.out.println("Passed all tests!");
      }
    
      public static void main(String[] args) {
        testNthFibonacci();
      }
    }
    
  8. dayOfWeek
    class MyCode {
    
      // This method takes a date represented by three integers,
      // the month (1-12), the day (1-31), and the year, and returns an
      // integer representing the day-of-week for that date, where
      // Sunday is 1, Monday is 2, and so on, and Saturday is 7.
      // While there are several ways to do this, you must use
      // this formula (from the most-excellent web site mathforum.org):
      //   N = d + 2m + [3(m+1)/5] + y + [y/4] - [y/100] + [y/400] + 2
      // Then the remainder when you divide N by 7 is the day-of-week,
      // where Saturday is 0 and Friday is 6.  Note that these values for
      // the days are not quite the same as those returned by this method.
      // Here is mathforum's description of the formula:
      //    "d is the number or the day of the month, m is the number
      //     of the month, and y is the year. The brackets around the
      //     divisions mean to drop the remainder and just use the
      //     integer part that you get.
      //     Also, a VERY IMPORTANT RULE is the number to use for the
      //     months for January and February. The numbers of these months
      //     are 13 and 14 of the PREVIOUS YEAR. This means that to find
      //     the day of the week of New Year's Day [of 1998], 1/1/98,
      //     you must use the date 13/1/97."
      // Note: you must make the adjustment to the month and year when
      // appropriate.  So, for example, the date of New Year's Day for
      // 1998 would be obtained in the natural way:  dayOfWeek(1, 1, 1998).
      // You may ignore the cases where the month, day, or year are out of bounds.
    
      public static int dayOfWeek(int month, int day, int year) {
        return 42; // replace this with your answer!
      }
    
      public static void testDayOfWeek() {
        System.out.print("Testing dayOfWeek... ");
        // On 2/5/2006, the Steelers won Super Bowl XL on a Sunday!
        assert(dayOfWeek(2, 5, 2006) == 1);
        // On 6/15/1215, the Magna Carta was signed on a Monday!
        assert(dayOfWeek(6, 15, 1215) == 2);
        // On 3/11/1952, the author Douglas Adams was born on a Tuesday!
        assert(dayOfWeek(3, 11, 1952) == 3);
        // on 4/12/1961, Yuri Gagarin became the first man in space, on a Wednesday!
        assert(dayOfWeek(4, 12, 1961) == 4);
        // On 7/4/1776, the Declaration of Independence was signed on a Thursday!
        assert(dayOfWeek(7, 4, 1776) == 5);
        // on 1/2/1920, Isaac Asimov was born on a Friday!
        assert(dayOfWeek(1, 2, 1920) == 6);
        // on 10/11/1975, Saturday Night Live debuted on a Saturday (of course)!
        assert(dayOfWeek(10, 11, 1975) == 7);
        System.out.println("Passed all tests!");
      }
    
      public static void main(String[] args) {
        testDayOfWeek();
      }
    }
  9. 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.
     

  10. 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...
     

  11. 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.
     

  12. 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?
     

  13. 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 "=="?
     

  14. 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.
     


Carpe diem!