Computer Science 15-100 (Lecture 18), Spring 2009
Homework 2
Due:  Thu 29-Jan-2009 at 11:59pm (email copy) and at Friday's class/recitation (identical physical copy)
(no late submissions accepted).


Read these instructions first!


  1. Short Answers
  2. Tracing
  3. Mystery Code
  4. isPerfectSquare
  5. medianof4
  6. digitAt
  7. sillyCalculator
  8. Painting Flags
  9. Bonus/Optional:  quadrantOfIntersection
  10. Bonus/Optional:  unitVolumePrismHeight

  1. Short Answers
    In the written portion of your submission, answer each of the following questions.  Be very brief, but show your work where appropriate.

    Assume that "x" and "y" are boolean values:
     
    1. Fill in the blanks with one of “always”, “sometimes”, or “never”.  Be sure to show your work, using truth tables to prove your answer.  The first problem is done for you to demonstrate.

      1. !(x || y)   ___sometimes____  equals (x && y)

            x    y    (x || y)   !(x || y)  (x && y)
            T    T        T           F        T
            T    F        T           F        F   
            F    T        T           F        F   
            F    F        F           T        F


        Note:  The truth table clearly shows that the two expressions are equal when x is true and y is false or when x is false and y is true, but are unequal when both x and y are false or both are true.

        Note:  the column labeled (x || y) is not part of the final answer, but is still important to include.  It is a “helper column”, and it simplifies the computation of the next column.  You should include helper columns as you deem necessary.

      2. (!!x)   ________________  equals x


      3. (x && !y)   ________________  equals (!x || !y)


      4. (x && !y)   ________________  equals !(x || !y)


      5. (x == !y)  _________________  equals ((!x && y) || (x && !y))


    2. Fill in the blank with a String literal to make this code snippet print “true”.  Note that there are many possible correct answers.

          String s = ________________________________ ;
          System.out.println(s.length() == (s.charAt(0) – s.charAt(2));
        
  2. Tracing
    In the written portion of your submission, indicate what each of the following will print or (if it is graphical) draw.  Do not run these programs.  Figure this out by hand.  Remember to show your work.

a)







 


 

b)










 


 

c)











 


 

  1. Mystery Code
    In the written portion of your submission, state what the following method does in general, and in just a few words of plain English.

    Hint:  while you should definitely trace the code in this problem by hand to make some sense out of it, you may also wish to actually test the code in a compiler with samples of your choosing, at least to verify that it works as you think it does!

    Note:  this method may seem a bit confusing, and it is.  There are some much easier, clearer, and more sensible ways to do the same thing.

    public static int mysteryMethod(int x, int y) {
      int a = x - y;
      int b = 1 - (3*a)/(3*a-1);
      return b*x + (1-b)*y;
     }

  2. isPerfectSquare
    Write the following method:
      public static boolean isPerfectSquare(int x)
    This method takes an integer value and returns true if it is a perfect square, and false otherwise.  The perfect squares are 0, 1, 4, 9, 16, 25,...

    Hint: you may want to use the Math.sqrt (why?), Math.round, and Math.abs methods.  Not sure how they work?  Look them up in the online API (and perhaps write one or two very short programs to experiment with them).

    Hint: x may be negative, and while no negatives can be perfect squares, you must return false and not crash in that case!

    Here is a test method for you:
      public static void testIsPerfectSquare() {
        System.out.print("Testing isPerfectSquare... ");
        assert(isPerfectSquare(-4) == false);
        assert(isPerfectSquare(-3) == false);
        assert(isPerfectSquare(-1) == false);
        assert(isPerfectSquare(0) == true);
        assert(isPerfectSquare(1) == true);
        assert(isPerfectSquare(2) == false);
        assert(isPerfectSquare(4) == true);
        assert(isPerfectSquare(99) == false);
        assert(isPerfectSquare(100) == true);
        assert(isPerfectSquare(101) == false);
        System.out.println("Passed all tests!");
      }


  3. medianOf4
    Write the following method:
      public static int medianOf4(int a, int b, int c, int d)
    This method takes four integer parameters and returns the median value, which is the average of the two middle values.  So if the values are 7, 2, 4, and 19, then the median is the average of 7 and 4, which is 11/2, or 5 (as we are using integer division here).  You may use Math methods here.

    Here is a test method for you:
      public static void testMedianOf4() {
        System.out.print("Testing medianOf4... ");
        assert(medianOf4(2, 5, 8, 99) == 6);
        assert(medianOf4(99, 2, 8, 5) == 6);
        assert(medianOf4(0, 0, 0, 0) == 0);
        assert(medianOf4(-3, -8, -2, -10101) == -5);
        System.out.println("Passed all tests!");
      }

  4. digitAt
    Write the following method:
       public static int digitAt(String s, int index)
    This method takes a String and an index and returns the integer value of the digit at the given index.  For example, given "84+23" and index 0, the method returns the value 8.  You may assume that the index is in bounds and also that there is a digit at that location of the String.

    Hint: you should not use the number 48 in your solution.  Instead, use '0', which means "the Unicode value of the character '0'", which happens to be 48.

    Here is a test method for you:
      public static void testDigitAt() {
        System.out.print("Testing digitAt... ");
        assert(digitAt("84+23",0) == 8);
        assert(digitAt("84+23",1) == 4);
        assert(digitAt("84+23",3) == 2);
        assert(digitAt("84+23",4) == 3);
        System.out.println("Passed all tests!");
      }

  5. sillyCalculator
    Write the following method:
      public static int sillyCalculator(String spec)
    This method takes a String which specifies a simple addition or subtraction problem, and returns the answer as an int value.  This is a very limited calculator, though, as the values must be positive, two-digit integers.  Also, there may not be any spaces or other characters in the spec, so the spec must be exactly 5 characters long.  For example, if the spec is "22+18", the method returns 40.  And if the spec is "30-84", the method returns -54.  You are not responsible for specs that do not obey these restrictions (so your code may even crash in such cases).

    Note: this method MUST use the digitAt method you just wrote.

    Hint: you may need to write a simple test program to determine the Unicode values of the characters '+' and '-'.

    Hint: remember not to use conditionals ("if" statements) here, even if you know how!  This can be done in just a few lines just using arithmetic.

    Here is a test method for you:
      public static void testSillyCalculator()
        System.out.print("Testing sillyCalculator... ");
        assert(sillyCalculator("84+23") == 107);
        assert(sillyCalculator("84-23") == 61);
        assert(sillyCalculator("23-84") == -61);
        assert(sillyCalculator("00-03") == -3);
        System.out.println("Passed all tests!");   
      }

  6. Painting Flags
    Note:  To paint the following flags, you will have to use Polygons and the fillPolygon method.  The following short example shows how these are used:
      public void paint(Graphics page) {
        page.setColor(Color.gray);
        page.fillRect(100, 50, 200, 150);
        Polygon p = new Polygon();
        p.addPoint(100, 50);   // left-top of rectangle
        p.addPoint(200, 125);  // center of rectangle
        p.addPoint(300, 50);   // right-top of rectangle
        page.setColor(Color.black);
        page.fillPolygon(p);
      }

    This code first fills a gray rectangle, then it creates a new Polygon object and adds 3 points to that object at the left-top, center, and right-top of the rectangle.  It then fills that Polygon in black, producing this result:

    Study the preceding example code carefully, change it as necessary (for example, changing the points or adding more or fewer points) to understand how Polygons work.

    Then, paint each of the following flags (one flag per Java file) using only filled rectangles and filled ovals.  You should use custom colors, matching the colors in the flags as closely as possible.  Also, your flags may not be fixed-sized, but rather they must entirely fill the window, even when the window is resized.  While the window's size may change, you may assume the window will be roughly "flag-shaped" -- you will not be graded on how your flags appear in, say, a tall thin window (which is not at all "flag-shaped").

    Note: All these flag images are from the very informational CIA World Factbook, which includes a flags-of-the-world page

    a. Kuwait
    (file:  Hw2FlagOfKuwait.java)
    (larger image with details)

    b.  Seychelles
    (file:  Hw2FlagOfSeychelles.java)
    (larger image with details)


  7. Bonus/OptionalquadrantOfIntersection
    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.

  8. Bonus/OptionalunitVolumePrismHeight
    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!