Java Programming Assignments

written by Keith Fenske
Copyright (c) 2002, 2005-2007 by Keith Fenske.  All rights reserved.

Java is a structured object-oriented language available on most computers.  See the Java home page by Sun Microsystems with an on-line Java Tutorial.  The examples below are Java applications, and will run in a terminal emulator window on any version of Java if you import the Lewis/Loftus keyboard class.  The names of the solution files are for viewing in your browser.  After you download the text file, look for the program's class name and rename the file name to match.  For example on Windows, a Java class called "Blackjack" should be in a "Blackjack.java" file.
 
print name and age using variables assignment solution
High/Low number guessing game assignment solution #1
solution #2
print all prime numbers less than 100 assignment solution #1
solution #2
chart with random numbers and a word assignment solution
Fibonacci sequence using recursive function calls assignment solution #1
Fibonacci sequence counting recursive function calls assignment solution #2
Fibonacci sequence using an explicit formula assignment solution #3
Fibonacci sequence using loops and an array assignment solution #4
draw a box around a text string assignment solution
reverse a text string assignment solution
calculate shared birthday probability assignment solution
print Pascal's Triangle assignment solution
Hangman word guessing game assignment solution
Blackjack card game assignment solution
Tic-Tac-Toe strategy game assignment solution
Tic-Tac-Toe (with graphical interface) web applet source code
Dots and Boxes (Lines and Boxes) web applet source code
Hexadecimal Text web applet source code
John Conway's Game of Life web applet source code
Maze Fog web applet source code
Reversi (Othello) web applet source code
obscure text utility (graphical) assignment solution
repeating calendar assignment solution
similar words (graphical) assignment solution
dump file utility (console) assignment solution
making change for a dollar assignment homework
find duplicate files assignment download
trim trailing spaces and tabs assignment download
echo command-line parameters assignment download


print name and age using variables

Write a Java application to print two lines of output with your name and your age.  The first line will have your name and the second line will have your age.  Use complete sentences as in the following example:
My name is Keith Fenske.
I am 21 years old.
Declare a String variable for your name and an int variable for your age.  Write both lines as a single concatenated string using one call to the System.out.println method.

High/Low number guessing game

High/Low is a number guessing game played as follows:
  1. The computer picks a random integer from 0 to 100 (inclusive).  Use the Math.random() method to generate a random number.
  2. The computer asks the user for a guess.
  3. The user types a number.  Use the Keyboard.readInt() method to read an integer from the keyboard.
  4. The computer checks that the number is from 0 to 100.  If the number is less than 0, or greater than 100, the computer will print an error message and ask again.  This means that you should ask for a number inside a while loop.
  5. If the user's number is less than the computer's number, then the computer will print a message saying that the number is "too low" and ask for a higher number.
  6. If the user's number is greater than the computer's number, then the computer will print a message saying that the number is "too high" and ask for a lower number.
  7. If the user's number is equal to the computer's number, then the computer will print a message congratulating the user, and the game will end.
Some suggestions for your program: Two solutions are available for this assignment.  The first solution does error checking in the same if-else statements as the high/low logic of the game.  The second solution uses a separate while loop to check the user's input.

print all prime numbers less than 100

Write a Java application to compute all prime numbers less than 100.  A number n>1 is prime if it is only divisible by 1 and by itself.  The first few prime numbers are 2, 3, 5, 7, 11, 13, 17, 19, 23, etc.

You may use any algorithm that can be easily and correctly extended to a larger limit such as 1,000 or 1,000,000 by changing only one number in one place in your program.  The following standard algorithm is from page 22 of "Discrete Mathematical Structures":

Question:  Why is it only necessary to test odd numbers less than or equal to the square root of n?

chart with random numbers and a word

This assignment is an exercise in nesting for loops and if-else statements, and in using the switch statement.  (The word "nesting" means that one for loop is inside another for loop, or inside an if-else statement.)  There are many parts to this program.  However, each part is simple.  Do one part at a time, and get each part working before you start the next part.

Consider the following example output from the teacher's version of this program:

What is the size of the chart?  (1 to 10)  4

+-----+-----+-----+-----+
|Keith| 529 | (5) | 31* |
+-----+-----+-----+-----+
| 51* |Keith|$9985|65228|
+-----+-----+-----+-----+
|20720|54090|Keith| (4) |
+-----+-----+-----+-----+
| 95* | 862 |$2262|Keith|
+-----+-----+-----+-----+
The program performs the following steps:
  1. Ask the user for an integer from 1 to 10.  Read the number with the Keyboard.readInt() method.  This number is the size of a chart.  For example, if the number is 4, then the chart has 4 rows and 4 columns.  Of course, if the number is not from 1 to 10, then your program must print an error message.
  2. The program then prints a chart.  Each entry in the chart is either a word or a number.  Each entry is five characters long.  To print the lines (boxes) in the chart, use the characters "+", "|", and "-".  Notice that the same horizontal line is drawn before the first row of the chart, between each row, and after the last row.  This would be a good place to make a second Java method to print the horizontal line.  Then your main() method can call the second method whenever it needs a horizontal line.
  3. The words in the chart are your name.  If your name is longer than 5 characters, then choose a shorter name.  Your name goes on all diagonal entries of the chart.
  4. The numbers in the chart are random numbers from 0 to 99999.  To generate the random numbers, you must use the following procedure:
  5. length from to example
    1 0 9 " (4) "
    2 10 99 " 31* "
    3 100 999 " 529 "
    4 1000 9999 "$9985"
    5 10000 99999 "65228"
The teacher's version of this program is 96 lines long including comments.  It has two for loops, two if-else statements, one switch statement, and a second method to print a horizontal line.  The second method is called printLine() and it takes one integer parameter for the number of columns to print.  To print the horizontal line, printLine() uses one for loop.

Fibonacci sequence using recursive function calls

Write a Java program to compute the Fibonacci sequence 1, 1, 2, 3, 5, 8, 13, 21, ... using the recursive function f(1) = f(2) = 1, f(n) = f(n-1) + f(n-2) as explained on page 95 of "Discrete Mathematical Structures".

You will need one main() method and one recursive method called f() to calculate the Fibonacci function.  After the main() method introduces itself, it will perform the following steps in a loop:

  1. Prompt the user for a parameter n from 1 to 99.
  2. If n is zero or negative, then the program ends.
  3. If n is positive, then:
The Fibonacci function will have one int parameter for n, and will return an int result for the function value f(n).  This function must be recursive.  To compute f(n) when n>2, the function must call itself twice: once for the value of f(n-1) and once for the value of f(n-2).

Questions:

The teacher's version of this program is 70 lines long including comments.

Fibonacci sequence counting recursive function calls

Your first Fibonacci program is very slow when calculating f(n) for large values of n.  The reason that it is slow is because each recursive function calls two more recursive functions, which both call two more functions, resulting in approximately O(2n) function calls before the result is computed.

For this assignment, make a copy of your first Fibonacci program.  Change the new file to count the number of calls to the Fibonacci function.  You will need a static class variable for counting because the calls are counted in the Fibonacci method and the total is used in the main() method.  Only class variables are shared by all methods in the same class.  The main() method must clear this class variable to zero before calling the Fibonacci function, and the Fibonacci function must increment the class variable each time it is called.

Otherwise, everything is the same as in the previous assignment: prompt the user for input, check the range of the input, call the Fibonacci function, print the results, and repeat until the input is zero or negative.

Questions:

The teacher's version of this program is 78 lines long including comments.

Fibonacci sequence using an explicit formula

Write a Java program that computes the Fibonacci sequence 1, 1, 2, 3, 5, 8, 13, 21, ... using an explicit formula as shown on page 99 of "Discrete Mathematical Structures".  An explicit formula computes elements in a sequence without recursion (referring to previous elements).  For the Fibonacci sequence, the explicit formula is:

explicit Fibonacci formula

Your main() method will be similar to the main() method in your first Fibonacci program.

The explicit Fibonacci function will have one int parameter for n, and will return a long result for the function value f(n).  Note that this result is bigger than in the first Fibonacci program (which only returned an int result).  Use double floating-point numbers to calculate the explicit formula.  You will need the Math.pow() and Math.sqrt() methods.  To convert the double floating-point result to a long integer, you should use the Math.round() method.

Questions:

The teacher's version of this program is 78 lines long including comments.

Fibonacci sequence using loops and an array

There is another way to compute the Fibonacci sequence.  This method is not in the textbook.  The problem with the first and second Fibonacci programs is that they are recursive and repeatedly calculate the same results without saving any of the previous results.  The problem with the third Fibonacci program is that floating-point numbers are "fuzzy" (not accurate) when doing integer calculations.

For this assignment, you will compute the Fibonacci sequence by saving previous results in an array.  This is much faster than the first two programs because its speed is O(n) instead of O(2n), and it is more accurate than the third Fibonacci program.

Your main() method will be similar to the main() method in the first three Fibonacci programs, except that the main() method can do the calculations inside a for loop.  Do not use a second method for the Fibonacci function in this assignment.

The array will be an array of long integers.  The array should have 100 elements.  The index of the first element in a Java array is zero (0).  The Fibonacci function is defined starting at f(1).  To avoid confusion about function notation and index variables, ignore the first element.  Then f(n) will be in array element n:

results[0] = 0;   // dummy value (not used)
results[1] = 1;   // initial value for f(1)
results[2] = 1;   // initial value for f(2)
Use a for loop to calculate results[3] to results[n].

Questions:

The teacher's version of this program is 64 lines long including comments.

draw a box around a text string

This assignment is practice in writing Java methods.  Other programming languages use the words "function", "procedure", or "subroutine".  In Java, the correct word is "method" because Java is an object-oriented language and methods can be attached to objects.

This assignment has three steps.  The same program is used for all three steps.  Please finish step #1 before starting step #2, and finish step #2 before starting step #3.


Step #1:

Write a small main() method that calls a boxLine() static class method with one integer parameter.  The parameter is the length of a horizontal line.  For example, the call boxLine(10) would print the following output:
+----------+
Test your boxLine() method by calling it from your main() method with various parameters greater than or equal to zero.


Step #2:

Now write a boxText() method that takes a string parameter and prints a box around the string.  For example, the call
boxText("Hello. How are you?");
would print the following output:
+-------------------+
|Hello. How are you?|
+-------------------+
Test your boxText() method by calling it from your main() method with various string parameters.  The boxText() method must call the boxLine() method to draw the horizontal lines.  You should put a blank line before the first horizontal line.


Step #3:

Now write a boxInfo() method that takes two parameters.  The first parameter is a string with a person's name.  The second parameter is an integer with that person's age.  The boxInfo() method calls the boxText() method with a message string created from the person's name and age.  For example, the call
boxInfo("Mickey Mouse", 73);
will call the boxText() method with the following string:
boxText("Mickey Mouse is 73 years old.");
and the output from boxText() would be:
+-----------------------------+
|Mickey Mouse is 73 years old.|
+-----------------------------+
Test your boxInfo() method by calling it from your main() method with various names and ages.  Use interesting names and correct ages.  For example, how old is Tyrannosaurus rex?  (Mickey Mouse made his screen debut on 18 November 1928 in "Steamboat Willie", a short black-and-white animated musical.)


Questions:

text.length
text.length()
The teacher's version of this program is 79 lines long including comments.

reverse a text string

This assignment uses Java strings and a Java method that returns a string result.  Consider the following example:
AppAccelerator(tm) 1.2.010 for Java (JDK 1.2), x86 version.
Copyright (c) 1997-1999 Inprise Corporation. All Rights Reserved.

Please type a string (or * to quit):
Hello. How are you?

original string: "Hello. How are you?"
reversed string: "?uoy era woH .olleH"
original string: "Hello. How are you?"

Please type a string (or * to quit):
*

Press Ctrl+C to terminate the application...

Step #1:

Write a reverse() method that takes one string parameter and returns a string result.  The characters in the result string are in reverse (opposite) order compared to the characters in the parameter string.  For example, the call
reverse("Hello. How are you?")
would return the following string as a result:
"?uoy era woH .olleH"
Start by setting the result string to an empty string.  Then append one character at a time from the parameter string.  Your reverse() method may only use char, int, or String data types, the String.charAt() method, and the String.length() method.  Your reverse() method may not use any other methods or data types.  You do not need a character array for this assignment.  Note that the parameter string can have zero or more characters.

Test your reverse() method by calling it from your main() method with various strings whose length is greater than or equal to zero.


Step #2:

Change your main() method to read input from the user in a loop.  For each input string, print the original string, the reversed string, and then the original string again.  Continue reading input until the input string is "*" (only a single asterisk character).

Your main() method must use the Keyboard.readString() method, your reverse() method, the String.equals() method, and the System.out.println() method.  The main() method must have only one variable: a string for the user's input.  The main() method may not use any other methods or variables.


Questions:

The teacher's version of this program is 61 lines long including comments.

calculate shared birthday probability

In any group of people, there is a probability that two or more people have the same birthday.  Write a Java program to calculate the minimum size of a group for a given probability.

The best way to solve this problem is to use the probability that a group of people do not share a birthday.  That is, that all people in the group have different birthdays.  Your program will ask the user for a probability p from 0 to 1 (inclusive), and will find the smallest group size n where the probability of different birthdays is less than or equal to p.  Your program will then print n and the calculated probability for that group size.

For n = 1, there is only one person, and one person must have a unique birthday.  For n = 2, the first person has a unique birthday, and the probability p2 that the second person has a different birthday is p2 = 364/365.  (Assume that each year has exactly 365 days: no leap years.)  The probability that a third person is born on a different day is:

p3 = 364/365  x  363/365
The general term is:
pk = 364/365  x  363/365  x  362/365  x  361/365  x  360/365  x  ...
Your program must work correctly for all values of p from 0 to 1, inclusive.

Questions:

The teacher's version of this program is 77 lines long including 33 lines of comments.

print Pascal's Triangle

Write a Java program to print the first fifteen lines of Pascal's Triangle, as shown on page 82 of "Discrete Mathematical Structures".  There is no input from the user.

This assignment has three steps.  The same program is used for all three steps.  Please finish step #1 before starting step #2, and finish step #2 before starting step #3.


Step #1:

Write a choose() method that takes two int parameters (n and r) and returns one long result.  choose() implements the combination function nCr (page 79) to calculate the number of combinations of n objects taken r at a time.

Test your choose() method by calling it from your main() method with various parameters.


Step #2:

Print the first 15 lines of Pascal's Triangle using the numbers calculated by your choose() method.  Put one space between the numbers.  The following example shows the lines for n=0 to n=9:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1

Step #3:

Now print the first 15 lines of Pascal's Triangle using your choose() method, with each line centered, as in the following example for n=0 to n=9:
             1
            1 1
           1 2 1
          1 3 3 1
         1 4 6 4 1
       1 5 10 10 5 1
      1 6 15 20 15 6 1
    1 7 21 35 35 21 7 1
   1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
The best way to do the centering is to convert each line into a string, subtract the length of the string from a fixed width (such as 72 characters), and divide the difference in half.  The number you calculate is the number of spaces to put before the first number on the line.


Your finished program must implement Step #3.  (Steps #1 and #2 are just to help you get started.)

Questions:

The teacher's version of this program is 92 lines long including comments.

Hangman word guessing game

Write a Java program to play the word guessing game called "Hangman".  Make the game interesting to play.  Your program should be friendly and should be polite and helpful if the user makes a mistake.

You may use any Java data types or methods that you want.

The following suggestions may be helpful:

  1. After you finish one game of Hangman, ask the user if he/she would like to play another game.  An answer of "yes" or "YES" means to play another game, and an answer of "no" or "NO" means to end the program.  What should your program do if the answer is anything else?
  2. Your program should choose a random word from a short list.  How will you put a list of words in your program?
  3. Each time the user makes a guess, he/she can guess one letter, or can guess the whole word.
  4. If the user guesses a letter correctly, then your program must show all occurrences of that letter in the word.
  5. If the user tries to guess the same letter twice, your program should politely tell the user that he/she has already guessed that letter, and shouldn't count this as a mistake.
  6. Guessing the whole word incorrectly counts as a mistake.
Questions: The teacher's version of this program is 266 lines long including comments. The teacher's program can do special words like "ice cream" and "x-ray".  All messages have correct English grammar.  For example, if the user guesses one correct letter in a word, then the program prints a message like this:
Yes, there is one letter "e" in the word.
If the same letter is found twice, then the program prints a message like this:
Yes, there are 2 letters "e" in the word.

Blackjack card game

Write a Java program to play the card game called "Blackjack" (also known as "Twenty-One").  Make the game interesting to play.  Find the rules by looking in a book about card games, or by searching on the internet.

The most difficult part of this game is shuffling a deck of imaginary cards....

The teacher's version of this program is 472 lines long including comments, and has a main() method plus 10 helper methods.  Eight of the helper methods are for shuffling, dealing, and displaying the cards.  The teacher's program keeps track of how many times the computer wins and how many times the user wins.  The teacher's program does not do betting.


Tic-Tac-Toe strategy game

Write a Java program to play Tic-Tac-Toe (Naughts and Crosses, Tick-Tack-Toe, X's and O's).

Begin by writing a program that plays a correct game, even if the program is very stupid.  Make the computer's move in a separate method that can be improved later.  Note that the user always moves first.

The most common board size in two-dimensional Tic-Tac-Toe is 3x3, meaning a square grid with three rows and three columns.  Board sizes larger than 3x3 are also possible: 4x4, 5x5, etc.  Board sizes of 1x1 and 2x2 are always won by the first player.  Write your game to work properly for any board size starting with 1x1.  Make the board size a declared constant in your program, such as:

final static int SIZE = 3;   // board grid is 3x3
The teacher's version of this program is 319 lines long including comments.  This program is so stupid that the computer moves randomly!

obscure text utility (graphical)

Write a graphical utility to disguise or obscure words in a text file.  As you have noticed by now, console applications that use the command-line interface and write to the user with System.out.println calls are not very convenient.  Take what you have learned about graphical programming while writing games and apply the same to a GUI application that reads from a file, makes some changes to the text, and writes the changed text to a new file.

Input will be changed by replacing lowercase letters ("a" to "z") with random lowercase letters, uppercase letters ("A" to "Z") with random uppercase letters, and digits ("0" to "9") with random digits.  Only these characters will be changed, and only on lines selected by the user.  Give the user the option of changing every line, every second line, third, fourth, fifth, sixth, tenth, or twelfth line.  Give the user the option of selecting lines either sequentially (for example, every tenth line) or randomly with a given probability (for example, one in ten).

Show the changed text in a scrolling output area.  Give the user a button to open an input file, according to the options selected.  Give the user another button to save the changed text in an output file, and a third button to exit from the application.

Communicate with the user through buttons, options, and messages written into the output text area.  You will need a main window ("JFrame") and standard Java dialog boxes to open and save files, but don't use other windows or pop-up dialog boxes -- not even for your error messages.  Error or informational messages must go into the output text area or other Java Swing components on your main window.  You must handle incorrect user input for the options and possible I/O errors when opening, reading, writing, or closing a file.  You may use any Java Swing classes that you need.  The sample solution is around 390 lines long and uses (among others): ActionListener, BorderLayout, Box, BufferedReader, FileReader, FileWriter, FlowLayout, JButton, JComboBox, JFileChooser, JFrame, JLabel, JPanel, JScrollPane, JTextArea, Math.random, and StringBuffer.

Write this program carefully, because you can re-use the graphical skeleton later for almost any quick-and-dirty file processing that you need, such as the "similar words" utility below.


repeating calendar

This is an exercise in using Java Calendar objects.  Write a Java console application (simple, not graphical) to find the minimum interval when the calendar repeats for every day of the year.  Limit your testing to a 99-year span starting in 2001.

While it is possible to be clever about testing dates (you could test only two special dates in each year), write your program to test every day in every month in each year of the interval.  For example, if you think that the calendar repeats every ten years (which it doesn't), then check that all days in 2001 have the same weekdays (days of the week) as the same days in 2011, all days in 2002 with all days in 2012, up to and including all days in 2010 with all days in 2020.

To do this, you only need basic Java concepts, standard I/O, the Calendar object, and about 100 lines of code.  The sample solution uses Calendar.DAY_OF_WEEK, Calendar.get, Calendar.getInstance, Calendar.JANUARY through Calendar.DECEMBER, Calendar.set, and System.out.println.

After you finish this application, write another to answer a question.  If you take the month and day from a date (such as 9 May 2001 or 2001/5/9) and reverse the numbers for the month and day (such as 2001/9/5 or 5 September 2001), what are the chances of: (1) getting an invalid date, (2) getting a different day of the week, and (3) getting the same day of the week?  Do you need to consider the same interval of years calculated above, or can you use a smaller interval to compute the same percentages?


similar words (graphical)

People make mistakes when they type numbers, words, almost anything.  The most common mistakes are:

Most mistakes with letters don't result in proper words.  Most mistakes with numbers do.  Consider telephone numbers.  If you change one digit or reverse two digits, you usually get a valid telephone number, which is a "wrong" number for you, but still someone answers and you have to excuse yourself.  This happens because telephone numbers use almost all possible combinations of digits.  It doesn't happen as often with words because there are many more combinations of letters than there are words, and words that we don't recognize become nonsense.

To avoid this problem with telephone numbers, don't assign every number.  How many to reserve depends upon how careful you want to be.  Hint: prime numbers are very helpful here, especially numbers that are relatively prime to ten.  Assign only those telephone numbers that have a certain remainder when divided by a chosen prime number.  The prime number 3 is too small, five won't work at all, seven is better, eleven beats seven, etc.  The bigger the prime number, the more error checking you have.  What's the smallest prime number that will catch each of the four categories of mistakes listed above (individually)?  What's the smallest prime number that will catch all four categories (collectively)?

You can't use prime numbers on words.  You can compare words to each other and choose only those words that can't be confused by the four categories listed above.  Words like this are very suitable for identifiers such as account names, user login IDs, or abbreviations.  Write a Java Swing application (graphical interface) that will accept words from the user, compare them against each other, and report which words are in conflict with which other words.  Make options to select or ignore the four categories of change.  Once you get that working, let the user read a list of "known" words from a plain text file, compare input words against the list, optionally add words to the list, and save the list back to a file.  You should also be able to test the list of "known" words against itself.

The sample solution has 1020 lines of code with the usual Java Swing components, file I/O, regular expressions, String and Vector objects, etc.  In many ways, it is an extension of the "obscure text" utility created previously.


dump file utility (console application)

Write a Java console application to dump the contents of a file in hexadecimal and as 8-bit ASCII text.  Don't prompt the user for the name of the input file; get the file name as a parameter (argument) on the command line.  Similarly, write the dump on standard output with System.out.println, which can be redirected to a file by the user with ">" on the command line.  You may add any options that you feel are necessary, and those options will appear on the command line as additional parameters/arguments.

File dump utilities are not the place for graphical user interfaces.  They must be fast, simple, and correct, because they will be used to dump very large files, and the resulting dump file is usually five times bigger than the original input file.  In this application, you will need to make several decisions based on speed.  For example, reusing StringBuffer objects is faster than creating temporary String objects (up to 20% faster in this application).  You will also need to recognize the difference between bytes and characters: the input file must be read as bytes, while the dump may be written as characters.

For traditional reasons to do with MS-DOS screen sizes, dump output is limited to less than 80 characters per line, not counting the newline character(s).  Bytes are listed individually, not as words, because of some confusion about which byte is the low-order byte in multi-byte words.  The file text is shown, if the characters are printable, or substituted with another character if not.  The following dump has been modified for short output lines, to fit on this web page:

Dumping file: C:\MSDOS.SYS
00000000  3B 53 59 53 0D 0A 5B 50  |;SYS..[P|
00000008  61 74 68 73 5D 0D 0A 57  |aths]..W|
00000010  69 6E 44 69 72 3D 43 3A  |inDir=C:|
   ...
000006E8  73 0D 0A 0D 0A           |s....   |
1,773 bytes dumped.
Each line begins with the offset from the beginning of the input file, in hexadecimal, followed by the dump bytes in hexadecimal, followed by the text characters.  You should decide how many input bytes are on each line, how many digits in the file offset, and which text characters are printable and which aren't.  Test your program on files of different sizes, especially very small files with only a few bytes or even zero bytes, and on some very large files of several megabytes. The sample solution will run as either a console or graphical application.  You are advised to finish your own program before looking at the sample solution, then rewrite your program completely using ideas from the sample.  Like most programming exercises, copying from the solution won't teach you anything at all.


making change for a dollar

In how many ways can you make change for one dollar (100 cents) using pennies (1-cent coins), nickels (5 cents), dimes (10 cents), and quarters (25 cents)?  The coins must add up to the exact total, and you may assume that you have as many coins as necessary of each value.  The order in which coins are selected is not significant; only the total number of coins of each value is important.  Some obvious answers are:

The best way to solve this problem is to write a recursive method (that is, a method that calls itself) to add one coin at a time to a list, until the total value of the list either equals or exceeds the desired total of one dollar.  There are many ways of implementing a list, because you only need to remember enough information to print solutions once they are found.  An array is not the best choice here; however, if you choose to use an array, do so in a way that doesn't waste space in the array.  (Arrays have an assumed length, while the number of coins varies.)

Next, write a second program to make change for any amount of money, using coins of any denomination.  Depending upon the country where you live, coins may be better known by names instead of their numeric values.

The instructor's minimal solution has 180 lines of code and runs as a console application (no graphical interface).  The names of the coins, the values of each coin, and the desired total are declared as "static final" constants at the beginning of the program.  There is no input from the user.  To change these parameters, the program must be recompiled, which is not very "user friendly".  It does, however, include good error checking and displays all 242 ways of making change for a dollar.  (Now you know!)


find duplicate files

When collecting a large number of files of any kind, there will be duplicates with the same file under two different names or in more than one place.  Write a Java application to find duplicate files by searching for files that have the same size and the same MD5 checksum.  Report possible duplicates to the user, who can then verify if the files are identical, either by inspection or by doing a byte-by-byte comparison with the "comp" command in DOS/Windows or the "cmp" command in UNIX.  What to do with files is the user's choice; the program does nothing except report the duplicates.

The sample solution for this assignment is a ZIP archive containing Java files and documentation in Adobe Acrobat PDF format.  Make your program act like the sample without copying any of the code, which by the way, has about 1420 lines including comments.


trim trailing spaces and tabs

Write a Java application to remove trailing blank spaces and tabs from the end of lines in plain text files.  Extra white space tends to accumulate when editing source programs in a graphical compiler such as the Java NetBeans IDE.  This isn't a big problem, but does waste file space and may occasionally affect the appearance of programs.

When reading (or writing) text files in Java, you have two choices: as bytes (8-bit) or as characters (16-bit Unicode).  Java prefers to work with Unicode characters, and in general, that is a much better way of handling text.  However, the conversion to Unicode prevents some low-level byte processing such as the exact representation of end-of-line characters.  UNIX and many newer systems like a single "newline" character (NL or 0x0A); older DOS and Windows applications want a "carriage return" (CR or 0x0D) followed by a "line feed" (LF or 0x0A) character.  Either bytes or characters are acceptable for this assignment.  Some factors to consider are:

Use the FileInputStream and FileOutputStream classes for byte I/O, or the FileReader and FileWriter classes for character I/O.  A console application is more suitable to this type of program that filters one input file and writes one output file.  If you choose to use a graphical interface, do something interesting other than having just an "Open File" and a "Save File" button.  (Perhaps you can highlight spaces and tabs that should/will be trimmed?  Allow the user to choose what font and size the text is displayed in?)  To view the exact contents of files, use the "dump file" utility created in a previous assignment. The sample solution has 660 lines of code including comments and options, runs as a console application, and reads text as characters not as bytes.


echo command-line parameters

We usually think of applications as programs that run, do a job for us, and then finish.  On large systems especially web servers, applications run for someone else, produce output that may be input for another program, and return status to the system.  Each time an application is run, there may be different parameters telling the program what to do, and those parameters are provided as arguments on the command line.  When applications are run from inside command scripts ("batch" files), one of the easiest mistakes to make is passing the wrong parameters.

Write a Java console application to echo (print) its command-line arguments on standard error (System.err).  Delimit the arguments in such a way that spaces are visible at the beginning or the end of each argument.  This dummy application can be substituted for a real application during testing, until you are certain that the correct parameters are being given to the program.

You should be able to do this with less than 30 lines of code, with comments.  You may use words like "simple" and "trivial" in your description.  An integer status can be passed back to the system (and hence to the command script) with the System.exit() method.  For this program, the number of arguments would be a good exit status.  How do you pass back more information that just one integer?


textbook reference

"Discrete Mathematical Structures" (4th edition) by Bernard Kolman, Robert C. Busby, and Sharon Cutler Ross (Prentice-Hall, 2000)


Copyright (c) 2002, 2005-2007 by Keith Fenske.  All rights reserved.