Computer Science APEA 15-100, Summer 2009
Homework 8
Due:  Tue 14-Jul-2009 at 8:59am (email copy only)
(no late submissions accepted).


Read these instructions first!


  1. Reading
  2. Finish Lab 8 (due Mon 13-Jul-2009, 8:59am)
  3. abcd
  4. binaryToDecimal
  5. Flag of the United States
  6. Simple Animation
  7. Bonus/Optional:  Flag of the European Union
  8. Bonus/Optional:  wordsearchContains

  1. Reading
    Finish reading the material for the next quiz, which covers 3.1, 3.2, 3.4, 3.5, 3.6 (just printf), 3.8, 5.1, 5,2, 5.3, 5.5, 5.7, and 5.8.  You will have time tomorrow and over the weekend to finish this reading.
     
  2. Finish Lab 8
    Finish all the examples from lab 8.  Include the solutions in your submission, all in one file named Lab8.java.  Note: the lab collaboration policy continues to apply to the lab problems.  So you can collaborate at will to solve these problems.  This only applies to the lab problems -- all other problems in this assignment are subject to the usual homework collaboration policy.
    This is due Mon 13-Jul-2009, 6:00pm.
     
  3. abcd
    Write the following method:
       public static int abcd()
    This method takes no parameters and returns the one-and-only 4-digit integer abcd (where a is non-zero) where the number abcd is equal to the product of  (ab) times (cd). So, for example, 2371 is not the answer because (23) * (71) = 8 * 7 = 56 != 2371. This method must not just return the hardcoded answer, but must use one or more "for" loops to search for the answer, and then return it.  Here is a test method for you:
      public static void testAbcd() {
        System.out.print("Testing abcd... ");
        int n = abcd();
        assert((n >= 1000) && (n < 10000));
        assert(pow(n/1000,(n/100)%10)*pow((n/10)%10,n%10) == n);
        System.out.println("Passed all tests!");
      }

    Helper Method:  pow

    In writing the "abcd" method, you will see that you will have to raise an integer value to an integer power.  Now, the Math class has a pow method, but it raises a double value to a double power, and returns a double.  We could convert that into an int by rounding it and then truncating, but that's a nuisance, especially if we have to do it more than once (which in fact you must for the abcd problem).  Instead, it would be handy to write our own method, pow, that takes two integers and returns the integer value of raising the first integer to the second integer.  Because we are writing this pow method specifically to help us with the abcd method, we say the pow method is a helper method.  Using helper methods is a form of decomposition, breaking a problem up into smaller, more easily manageable problems.  Here is the complete description for the helper method pow that you must write to solve the abcd problem:

    Write the following method:
       public static int pow(int a, int b)
    This method takes two integers, a and b, and returns the integer value ab.  If b is less than 0, the method just returns 0.  As usual, do not worry about overflow.  Here is a test method for you:

      public static void testPow() {
        System.out.print("Testing pow... ");
        assert(pow(2, -1) == 0);
        assert(pow(2, 0) == 1);
        assert(pow(2, 1) == 2);
        assert(pow(2, 5) == 32);
        assert(pow(-2, 5) == -32);
        assert(pow(-2, 6) == 64);
        System.out.println("Passed all tests!");
      }

    Note:  When writing pow, you must use a loop, and you may not use any Math methods.  In the loop, keep multiplying by "a", and keep doing this until you have multiplied "b" times. 
     

  4. binaryToDecimal
    Write the following method:
       public static int binaryToDecimal(String s)
    This method takes a (possibly-null) string s that represents a non-negative binary number and returns the decimal equivalent of that number as an int. If the string is null, or empty, or contains any characters besides '0' or '1', the method should return -1  As usual, do not worry about overflow. While there are several ways to solve this problem, you must use an approach that requires a loop in which you inspect each digit of the binary number in turn as you construct the result.  Here is a test method for you:
      public static void testBinaryToDecimal() {
        System.out.print("Testing binaryToDecimal... ");
        assert(binaryToDecimal("0") == 0);
        assert(binaryToDecimal("1") == 1);
        assert(binaryToDecimal("10") == 2);
        assert(binaryToDecimal("11") == 3);
        assert(binaryToDecimal("01001") == 9);
        assert(binaryToDecimal("11001") == 25);
        assert(binaryToDecimal("This is not a binary number!") == -1);
        assert(binaryToDecimal("") == -1);
        assert(binaryToDecimal(null) == -1);
        System.out.println("Passed all tests!");
      }

    Hint #1:  Not sure about counting in binary?  Try this page:  http://en.wikipedia.org/wiki/Binary_numeral_system#Counting_in_binary
    Or for more fun, try this page:  http://en.wikipedia.org/wiki/Finger_binary

    Hint #2:  In base 10 (decimal, what you are used to), say you have a number (say, 32) and you wish to add a digit (say, 4) to its right end (hoping to get 324).  To do this, multiply the number by 10 (320 * 10 = 320) and add the new digit (320 + 4 = 324 -- hurray!).  The same approach works in binary, only instead of multiplying by 10 (the base of our decimal system), we multiply by 2 (the base of the binary system).  So, if we have the binary number 110 (the number 6 in decimal), and we wish to add a 1 to the right, we multiply 110 times 2 (which is written as 10 in binary) to get 1100 in binary (or 12 in decimal, and indeed 6*2 = 12) and then add 1 to get 1101 in binary, which is 13 in decimal.  Why is this a hint?  Because this is the simple way to solve this problem.  According to this algorithm, you can solve this problem by starting your answer at zero, and iterating over the string from left-to-right, where for each character (representing a digit) you double your current answer and then add the next digit to it.  That's it.

    Hint #3:  For this and other problems in this assignment, you may need to determine the length of a string.  This is done with the length method, as the following code demonstrates:

    class MyCode {
      public static void main(String[] args) {
        String s = "Carpe diem";
        int n = s.length();
        System.out.println(n);  // prints 10
      }
    }
  5. Flag of the United States
    In the file Hw8FlagOfTheUnitedStates.java, write a program that displays the flag of the United States, stars and all:
      (larger image with details)
    You may use the star code from class.  Hint:  one way to look at the stars is in the form of two separate rectangular patterns -- an outer 5x6 pattern of 30 stars and an inner 4x5 pattern of 20 stars (where each row/column of the inner pattern is nestled between two rows/columns of the outer pattern).  While not required, you may want to use this hint in drawing the stars.
     
  6. Simple Animation
    In a file named Hw8SimpleAnimation.java, write this Simple Animation.

    Note:  If this applet does not run in your web browser, you can try running this equivalent jar file:
       ballAroundSquare.jar

    Note that the blue box is the largest square you can draw with a 10-pixel margin around it (so you will take the minimum of the width and height when computing the size of the square), and that the circle pauses on the corners and is red while it pauses.

    Hint:  the animation itself does not pause when the circle is on the corner -- the timer keeps firing away as normal.  Only your logic must basically ignore the timer for a little while at the right times.
     
  7. Bonus/Optional:  Flag of the European Union
    In the file Hw8FlagOfTheEU.java, write a program that displays the flag of the European Union:
      (larger image with details)

     
  8. Bonus/Optional:  wordsearchContains
    Write the following method:
       public static boolean wordsearchContains(String wordsearch, String word)
    This method takes a two strings, the first representing a wordsearch (stored in a single string!), and returns true if the second string occurs in that wordsearch and false otherwise.

    To represent a wordsearch as a string, we simply store each row concatenated to the next where we separate the rows with a | (that is, a vertical bar, or a pipe).  So, consider this wordsearch:

    t a c w
    n o o c
    d o g x

    The rows are: "tacw", "nooc", and "dogx", so we represent the entire wordsearch as: "tacw|nooc|dogx".
    Note that this wordsearch contains:

    cat
    cod
    coon
    dog
    ox


    You are guaranteed the wordsearch contains only lowercase letters, and that the rows are all the same positive length (you do not need to handle other cases in any way).

    Here is a test method for you:
      public static void testWordsearchContains() {
        System.out.print("Testing wordsearchContains... ");
        // These tests cover this wordsearch:
        //   t a c w
        //   n o o c
        //   d o g x
        assert(wordsearchContains("tacw|nooc|dogx", "cat"));
        assert(wordsearchContains("tacw|nooc|dogx", "cod"));
        assert(wordsearchContains("tacw|nooc|dogx", "coon"));
        assert(wordsearchContains("tacw|nooc|dogx", "dog"));
        assert(wordsearchContains("tacw|nooc|dogx", "ox"));
        assert(!wordsearchContains("tacw|nooc|dogx", "caw"));
        assert(!wordsearchContains("tacw|nooc|dogx", "cow"));
        assert(!wordsearchContains("tacw|nooc|dogx", "con"));
        assert(!wordsearchContains("tacw|nooc|dogx", "dogs"));
        assert(!wordsearchContains("tacw|nooc|dogx", "ax"));
        System.out.println("Passed all tests!");
      }

    Note:  This approach of representing a 2-dimensional board in a 1-dimensional string is not a very good idea.  Soon, we will learn about other ways we can more naturally represent this data, such as in a 2-dimensional array.


Carpe diem!