CS 367-5 - Spring 2000
Program 2

Due Date

    Tuesday March 7th, 11:59 pm

Announcements

    You may have to hit the reload button to see the most recent announcements

    • 6:02 pm Mar 6: Too many people have asked me for help with CodeWarrior for me to ignore them much longer. I discuss how to change the Main Class, as well as how to give command line arguments.
    • 1:40 pm Mar 1: Several people have asked me what the initial capacity for the Deque should be. I recommend 10: this is the default capacity given to the Vector in the Vector class.
    • 10:19 pm Feb. 29: Made changes to the placeQueens method, insert description in BucketSort section, and method header for bucketSort. See the mail message I sent describing the changes
    • 8:34 am Feb 24: Updated the documentation for the toString method of the Deque class
    • 12:26 am Feb 23: Updated the Chessboard class so that it now has a copy constructor. This constructor may be easier to use than the clone() method. See the updated ChessBoard javadoc

Specifications

    In this programming assignment, you will receive experience programming recursive algorithms, a data structure, and a sorting routine. In addition, you will analyze the running times of many aspects of what you implement.

    There are two parts to this assignment. You must complete both parts, which are described below.

    Hand in all files to:

      cs367-5/handin/<your login>/P2

    As with all assignments, your grade will be based upon your correctness and your style.

    Make sure you follow the naming convention that you are told to follow. This is so that we can fully test your programs to determine your grade. If we can not test your program, we will assume that it does not work correctly.

    N-Queens Problem

    Introduction

    In chess, the queen is the most powerful piece because of the various ways in which she can attack. The queen may attack either horizontally, vertically, or diagonally along the board. The ways in which a queen is capable of moving are illustrated below:
    ---------------------------------
    | + |   |   | + |   |   | + |   |
    ---------------------------------
    |   | + |   | + |   | + |   |   |
    ---------------------------------
    |   |   | + | + | + |   |   |   |
    ---------------------------------
    | + | + | + | Q | + | + | + | + |
    ---------------------------------
    |   |   | + | + | + |   |   |   |
    ---------------------------------
    |   | + |   | + |   | + |   |   |
    ---------------------------------
    | + |   |   | + |   |   | + |   |
    ---------------------------------
    |   |   |   | + |   |   |   | + |
    ---------------------------------
    
    The queen is placed where the "Q" is, and all the places the queen may move are illustrated by the "+". The "|" and "-" marks are supposed to show the outlines of the squares on the chess board.

    A popular thought problem with chess enthusiasts involves placing n queens on an otherwise empty n-by-n board, arranged in such a fashion that no queen may take any other. It will be your task to find and print all such arrangements. You will get assistance though: you will be using my representation of a chess board, as well as a recursive algorithm to place all of your queens.

    A naive approach to solving this problem would be to simply try all possible combinations. For instance, if you had an 8-by-8 chessboard and were therefore trying to place 8 queens, there are 64 choose 8 possible combinations, or roughly 4.4 billion combinations. If it takes 1 millisecond to test each configuration, it will take 4.4 million seconds in all: a mere 51 days or so.

    A better approach is to realize that we can only place one queen in the first row, one queen in the second row, and so on. You will take advantage of this fact in your implementation.

    I have supplied a ChessBoard.class, which you can use to initialize your chess board, place queens on the board at legal spots (that is, at spots which will not be taken by other queens), and print out the results. You should be sure to read the Java Documentation to see how this class operates. The class allows you to place queens at legal positions on the board.

    Below I give an algorithm which summarizes how you might consider structuring your code to solve this problem:

    placeQueens(board, row)
    Input: A ChessBoard board, and the row in which to place the next queen. Note the board already has a legal configuration of queens for rows 0 through (rows - 1).

    for columns 0 through length(board) - 1 
        // save the board so that recursive calls will not affect board's state
        savedBoard = clone(board)
        if placeQueen(savedBoard, row, column) is successful
            if row == length(board) - 1    
                // the base case: we have finally succeeded, so print the board
    	    print(savedBoard)
            else 
    	    // make recursive call to place queen on next row
    	    placeQueens(savedBoard, row+1)
    

    What you must hand in

    You will be solving the n-Queens problem. Your executable code must be contained in a file called Queens.java. Your program should use a single command line argument, which is the size of the board. If no command line argument is given, use a board size of 8. You may ignore all NumberFormatExceptions. Your program should then find all valid configurations, and print each out using the toString() method in the ChessBoard class. Please place two blank lines between each chessboard. I have supplied a sample file which shows all of the valid configurations for a board size of 5, so that you can see what is expected of you. Hand in Queens.java and any other java files you write to your P2 handin directory.

    Points to Ponder

    This is not something you have to hand in, but is something for you to consider: place and justify an upper bound on the total number of calls to placeQueens you will have to make.

    Part 2: Bucket Sort using Deques

    Introduction

    In this part of the assignment, you will use a new data structure to implement a new sorting technique.

    The new data structure you are to implement is known as a double-ended queue, often called a deque. A deque is similar to stacks and queues, except that deques allow full access at both the front and rear of the structure. That is, you are allowed to add to the front and rear (addFront, addBack), remove from the front and rear (removeFront, removeBack), and peek at the front and the back (peekFront, peekBack). As with stacks and queues, it is possible to set up our deque so that all of these operations can be performed in constant time (O(1)). There are also methods to check the number of elements in the Deque (size), checks if there are any elements in the deque (isEmpty), and a method which returns a String representation of the Deque (toString).

    A sorting technique which we did not cover in class is called bucket sort. Intuitively, here is how it works:

    To perform bucket sort, we assume that the input is an unsorted deque called D, which has n elements in it, with all elements of D between 0 and 1. The program creates an n-element array, B, of deques. These deques are referred to as buckets. Each bucket will receive a certain range of numbers. In particular, the ith bucket will receive all elements in D in the range [i/n, (i+1)/n). When we place an element into a bucket, we make sure to insert it so that the bucket is in sorted order.

    After we have placed all the elements in D into its corresponding bucket, we remove all elements from each bucket and replace them in D.

    Here is pseudocode describing this process:

    bucketSort(D)
    Input: An unsorted deque D with n elements, distributed in the range [0, 1)
    Postcondition: The elements of D are sorted in ascending order

        create an array of deques of size n called B
        for i = 0 to n-1
            value = remove from front of D
            bucket_index = (int) (n*value)
            insert value into deque B[bucket_index] (described below)
        for i = 0 to n - 1
            while B[i] is not empty
                value = remove from front of B[i]
                put value at rear of D
    
    insert(B, x)
    Input: A deque of values in sorted order, B; a value into be placed in the B, x
    Postcondition: x has been inserted into B, which will still be sorted
        create a temporary deque, tmp
        while B is not empty and front of B < x
            remove from the front of B and add it to front of tmp
        add x to the front of B
        while tmp is not empty
            add the front of tmp to the front of B
    

    What you must hand in

    Your task will be to implement a deque structure and bucket sort as they were described above. Your Deque structure should be created in a file called Deque.java. Your deque must follow at least this Deque interface description. You may expand upon the interface if you wish. Try to implement your deque in such a way that all operations can be performed in O(1) time and your deque is capable of holding an arbitrary number of values. If your deque does not do both of these, you will not receive full credit for the assignment. Turn in any support classes you create for your Deque class. You must also hand in a class called BucketSort.java, which must contain the method described by the following header:

      public static void bucketSort(Deque unsorted)

    You may write helper methods if you wish. Also, as comments in BucketSort.java you must answer the following questions:

    • What is the best-case running time of your implementation of bucket sort? Justify this time. Name at least one case for which that time occurs.
    • What is the worst-case running time of your implementation of bucket sort? Justify this time. Name at least one case for which this time occurs.

    For all aspects of what you are handing in, list any assumptions that you are making.

    Questions to ponder

    You are not required to answer these questions, but may be typical of questions I might ask of you on an exam.
    • How might you modify the description of bucket sort given above to use stacks instead of deques? Repeat this question for queues and linked lists. Does this effect the running time for the best and worst cases?
    • How might you modify the description of bucket sort to take doubles for any range of doubles? How about for integers? Does this effect the running time for the best and worst cases?
    • Is the implementation of bucket sort in place? Stable? If not, is it possible change the description so that it is?

Summary

    You must hand in at least the following three files:
    • Queens.java
    • Deque.java
    • BucketSort.java
    In addition, you should hand in any support files. Do not forget to answer the required questions posed to you and to follow the interface given to you.