Computer Science 15-100 (Sections S-V), Fall 2008
Homework 3 Practice
Due:  Never.  This is not assigned work.


Note:  You may not use Java concepts we have not yet covered, including arrays, or methods from any classes in java.util.* to solve these problems.  Also, you may only use the charAt and length methods from the String class. While these other methods or techniques may be helpful, every problem here is solvable without them.


Start with this file:  Hw3Practice.java

It contains these practice problems:

  1. kthDigit
  2. isPalindromicNumber
  3. goldbachPrime
  4. largestInACountedList
  5. largestInASentinelList
  6. largestInAStringTerminatedList
  7. largestInAUserTerminatedList
  8. wapipediaLookup

// Hw3Practice.java

import java.util.Scanner;
import java.io.PrintStream;

public class Hw3Practice {

  ////////////////////////////////////////////////////
  /// kthDigit
  ////////////////////////////////////////////////////

  // This method takes two int values, n and k, and returns the
  // kth digit (from the right) of the number n.  If k==0, this
  // returns the 1's digit.  If k==1, this returns the 10's digit.
  // If k==2, this returns the 100's digit.  And so on.  The method
  // assumes n has leading zeroes as needed.  Negative values of n
  // have the same results as their corresponding positive values.
  // If k is negative, the method returns -1.
  public static int kthDigit(int n, int k) {
    return 42;
  }

  public static void testKthDigit() {
    System.out.print("Testing kthDigit... ");
    assert(kthDigit(357,-1) == -1);
    assert(kthDigit(357,0) == 7);
    assert(kthDigit(357,1) == 5);
    assert(kthDigit(357,2) == 3);
    assert(kthDigit(357,3) == 0);
    assert(kthDigit(-357,1) == 5);
    System.out.println("Passed all tests!");
  }

  ////////////////////////////////////////////////////
  /// isPalindromicNumber
  ////////////////////////////////////////////////////

  // This method takes an int value and returns true if it is
  // palindromic -- the same forwards as backwards -- and false otherwise.
  // The method MAY NOT CONVERT THE NUMBER TO A STRING or use
  // Strings in any way.
  // No negative numbers are palindromic.
  public static boolean isPalindromicNumber(int n) {
    return false;
  }

  public static void testIsPalindromicNumber() {
    System.out.print("Testing isPalindromicNumber... ");
    assert(isPalindromicNumber(-1) == false);
    assert(isPalindromicNumber(0) == true);
    assert(isPalindromicNumber(1) == true);
    assert(isPalindromicNumber(12321) == true);
    assert(isPalindromicNumber(1221) == true);
    assert(isPalindromicNumber(122) == false);
    System.out.println("Passed all tests!");
  }

  ////////////////////////////////////////////////////
  /// goldbachPrime
  ////////////////////////////////////////////////////

  // The famous Goldbach Conjecture states that every even number
  // greater than 2 is the sum of two primes.  While it has been
  // verified to very large numbers, its proof remains one of the great
  // unsolved problems in mathematics.  Here, we will simply verify
  // Goldbach's Conjecture for relatively small even numbers.

  // This method takes an int value n and returns the smallest prime
  // number p that confirms Goldbach's Conjecture for n (because it
  // is part of the sum of two primes that equals n).  For example,
  // if n equals 12, we note that 12 = 5 + 7, so the method returns 5.
  // If n is odd or if n is less than 4, the method returns -1.
  public static int goldbachPrime(int n) {
    return 42;
  }

  public static void testGoldbachPrime() {
    System.out.print("Testing goldbachPrime... ");
    assert(goldbachPrime(4) == 2);
    assert(goldbachPrime(6) == 3);
    assert(goldbachPrime(8) == 3);
    assert(goldbachPrime(10) == 3);
    assert(goldbachPrime(12) == 5);
    assert(goldbachPrime(5) == -1);
    assert(goldbachPrime(2) == -1);
    assert(goldbachPrime(1) == -1);
    assert(goldbachPrime(0) == -1);
    assert(goldbachPrime(-4) == -1);
    System.out.println("Passed all tests!");
  }

  ////////////////////////////////////////////////////
  /// largestInACountedList
  ////////////////////////////////////////////////////

  // This method takes one parameter, a String containing space-separated
  // int values, where the first int value is n followed by n more int values,
  // and returns the largest value among those values (not including n itself).
  // If n is non-positive, or if there are not enough int values to complete
  // the problem, or if the String is null, the method returns -1.
  // Hint: use a Scanner over the string as input!
  public static int largestInACountedList(String s) {
    return 42;
  }

  public static void testLargestInACountedList() {
    System.out.print("Testing largestInACountedList... ");
    assert(largestInACountedList("1 3") == 3);
    assert(largestInACountedList("1 -3") == -3);
    assert(largestInACountedList("4 3 6 2 5") == 6);
    assert(largestInACountedList("4 3 6 2 5 9") == 6);
    assert(largestInACountedList("4 -3 -6 -2 -5") == -2);
    assert(largestInACountedList(null) == -1);
    assert(largestInACountedList("") == -1);
    assert(largestInACountedList("0") == -1);
    assert(largestInACountedList("5 1 2 3 4") == -1); // not enough!
    System.out.println("Passed all tests!");
  }

  ////////////////////////////////////////////////////
  /// largestInASentinelList
  ////////////////////////////////////////////////////

  // This method takes one parameter, a String containing space-separated
  // int values, terminated by the sentinel value -1,
  // and returns the largest value among those values (not including the sentinel).
  // If there are not enough int values to complete
  // the problem, or if the String is null, the method returns -1.
  // Hint: use a Scanner over the string as input!
  public static int largestInASentinelList(String s) {
    return 42;
  }

  public static void testLargestInASentinelList() {
    System.out.print("Testing largestInASentinelList... ");
    assert(largestInASentinelList("3 -1") == 3);
    assert(largestInASentinelList("-3 -1") == -3);
    assert(largestInASentinelList("3 6 2 5 -1") == 6);
    assert(largestInASentinelList("3 6 2 5 -1 9") == 6);
    assert(largestInASentinelList("-3 -6 -2 -5 -1") == -2);
    assert(largestInASentinelList(null) == -1);
    assert(largestInASentinelList("") == -1);
    assert(largestInASentinelList("0") == -1);
    assert(largestInASentinelList("1 2 3 4") == -1);
    System.out.println("Passed all tests!");
  }

  ////////////////////////////////////////////////////
  /// largestInAStringTerminatedList
  ////////////////////////////////////////////////////

  // This method takes one parameter, a String containing space-separated
  // int values, and returns the largest value among those values.
  // If there are not enough int values to complete
  // the problem, or if the String is null, the method returns -1.
  // Hint: use a Scanner over the string as input!
  public static int largestInAStringTerminatedList(String s) {
    return 42;
  }

  public static void testLargestInAStringTerminatedList() {
    System.out.print("Testing largestInAStringTerminatedList... ");
    assert(largestInAStringTerminatedList("3") == 3);
    assert(largestInAStringTerminatedList("-3") == -3);
    assert(largestInAStringTerminatedList("3 6 2 5") == 6);
    assert(largestInAStringTerminatedList("3 6 2 5 9") == 9);
    assert(largestInAStringTerminatedList("-3 -6 -2 -5") == -2);
    assert(largestInAStringTerminatedList(null) == -1);
    assert(largestInAStringTerminatedList("") == -1);
    assert(largestInAStringTerminatedList("0") == 0);
    assert(largestInAStringTerminatedList("1 2 3 4") == 4);
    System.out.println("Passed all tests!");
  }

  ////////////////////////////////////////////////////
  /// largestInAUserTerminatedList
  ////////////////////////////////////////////////////

  // This method works like the previous method (largestInATerminatedList),
  // only it gets its input from the user (and prints its result
  // rather than returning it), and after each pass asks the user
  // whether or not to continue.
  // The method must have exactly this I/O (with user input _underlined_):
  //   Enter value #1:  _3_
  //   Continue? [y/n]  _y_
  //   Enter value #2:  _-4_
  //   Continue? [y/n]  _n_
  //   Max value = 3.
  public static void largestInAUserTerminatedList() {
    System.out.println("YOU WRITE THIS!");
  }

  public static void testLargestInAUserTerminatedList() {
    System.out.print("Testing largestInAUserTerminatedList.. ");
    System.out.println("Manual testing required!");
    System.out.println("---------------------------------------");
    largestInAUserTerminatedList();
    System.out.println("---------------------------------------");
    System.out.println("   ... Passed all tests (if it looks right!)");
  }

  ////////////////////////////////////////////////////
  /// wapipediaLookup
  ////////////////////////////////////////////////////

  // This method takes one String parameter, a one-word topic, and
  // returns the plain text body of the wapipedia page on that
  // topic.  Note that wapipedia is a simplified version of
  // wikipedia designed for mobile phones, but therefore also
  // more useful for programmatic access (like this!).
  // Here is the URL for the wapipedia page on celery:
  //   http://www.wapipedia.org/wapipedia/mobiletopic.php?s=Celery
  // If there is no such topic, or the topic string is null, or any other error,
  // the method should return null;
  // Note that if there is no such topic, wapipedia will return a page with
  // something like this:
  //   sorry, I couldn't find the article for <your topic goes here>
  // Hint: This method would be much easier to write if you wrote your own
  // "contains" helper method, which takes two Strings and returns true
  // if the first string contains the second one (or, if you wish, you
  // may use the String.contains method only for this method).
  public static String wapipediaLookup(String topic) {
    return "42";
  }

  public static void testWapipediaLookup() {
    System.out.print("Testing wapipediaLookup... ");
    assert(wapipediaLookup("NP-Complete").contains("the most difficult problems"));
    assert(wapipediaLookup(null) == null);
    assert(wapipediaLookup("ThisTopicDoesNotExist") == null);
    System.out.println("Passed all tests!");
  }

  ////////////////////////////////////////////////////
  /// helper methods for reading from files + web
  ////////////////////////////////////////////////////

  // Convenient helper method for reading from a file.
  // Returns null if the file is not found.
  // You are responsible for using this method, but not
  // for writing it (neither on homeworks or tests)!
  public static Scanner getFileScanner(String filename) {
    Scanner scanner = null;
    try { scanner = new Scanner(new java.io.File(filename)); }
    catch (Exception e) {
      // System.out.println("File not found:" + filename);
      return null;
    }
    return scanner;
  }

  // Convenient helper method for writing to a file.
  // You are responsible for using this method, but not
  // for writing it (neither on homeworks or tests)!
  public static PrintStream getFilePrintStream(String filename) {
    PrintStream out = null;
    try { out = new PrintStream(new java.io.File(filename)); }
    catch (Exception e) {
      System.out.println("Error opening file " + filename);
      return null;
    }
    return out;
  }

  // Convenient helper method for reading from a web page (url) as plain text.
  // Returns null if there are any problems.
  // You are responsible for using this method, but not
  // for writing it (neither on homeworks or tests)!
  public static Scanner getUrlTextScanner(String url) {
    Scanner scanner = null;
    try {
      final StringBuffer sb = new StringBuffer();
      java.io.InputStreamReader reader = new java.io.InputStreamReader(
                                      new java.net.URL(url).openStream());
      javax.swing.text.html.HTMLEditorKit.ParserCallback parser =
        new javax.swing.text.html.HTMLEditorKit.ParserCallback() {
          public void handleText(char[] data, int pos) {
            if (data != null) sb.append(data);
          }
          public void handleSimpleTag(javax.swing.text.html.HTML.Tag tag,
                            javax.swing.text.MutableAttributeSet a,
                            int pos) {
           if (tag.breaksFlow()) sb.append("\n");
          }
        };
      new javax.swing.text.html.parser.ParserDelegator().parse(reader, parser, true);
      scanner = new Scanner(sb.toString());
    }
    catch (Exception e) {
      System.out.println("Error opening text reader for url: " + url);
      return null;
    }
    return scanner;
  }

  ////////////////////////////////////////////////////
  /// additional test methods and helper methods
  ////////////////////////////////////////////////////

  public static boolean almostEqual(double d1, double d2) {
    double epsilon = 0.000001;
    return (Math.abs(d2 - d1) < epsilon);
  }

  public static void checkAssertsAreEnabled() {
    boolean assertsEnabled = false;
    try { assert(false); }
    catch (Throwable t) { assertsEnabled = true; }
    if (!assertsEnabled)
      throw new RuntimeException("assert statements not enabled!");
  }

  public static void testAll() {
    testKthDigit();
    testIsPalindromicNumber();
    testGoldbachPrime();
    testLargestInACountedList();
    testLargestInASentinelList();
    testLargestInAStringTerminatedList();
    testLargestInAUserTerminatedList();
    testWapipediaLookup();
  }

  ////////////////////////////////////////////////////
  /// main method
  ////////////////////////////////////////////////////

  public static void main(String[] args) {
    checkAssertsAreEnabled();
    testAll();
  }
}

Carpe diem!