This assignments consists of three parts. First, write a library of static methods that performs geometric transforms on polygons. Next, write a program that plots a Sierpinski triangle. Finally, develop a program that plots a recursive pattern of your own design.
Part 1. In this part, you will write a library of static methods that performs various geometric transforms on polygons. Mathematically, a polygon is defined by its sequence of vertices (x0, y0), (x1, y1), (x2, y2), …. In Java, we will represent a polygon by storing the x– and y-coordinates of the vertices in two parallel arrays x[] and y[].
public class Transform2D {
// Returns a new array object that is an exact copy of the given array.
// The given array is not mutated.
public static double[] copy(double[] array)
// Scales the polygon by the factor alpha.
public static void scale(double[] x, double[] y, double alpha)
// Translates the polygon by (dx, dy).
public static void translate(double[] x, double[] y, double dx, double dy)
// Rotates the polygon theta degrees counterclockwise, about the origin.
public static void rotate(double[] x, double[] y, double theta)
// Tests each of the API methods by directly calling them.
public static void main(String[] args)
}
Note that the transformation methods scale(), translate() and rotate() mutate the polygons. Here are some example test cases (tests for copy() are not shown):
Part 2. The Sierpinski triangle is an example of a fractal pattern like the H-tree pattern from Section 2.3 of the textbook.
The Polish mathematician Wacław Sierpiński described the pattern in 1915, but it has appeared in Italian art since the 13th century. Though the Sierpinski triangle looks complex, it can be generated with a short recursive function. Your main task is to write a recursive function sierpinski() that plots a Sierpinski triangle of order n to standard drawing. Think recursively: sierpinski() should draw one filled equilateral triangle (pointed downwards) and then call itself recursively three times (with an appropriate stopping condition). It should draw 1 filled triangle for n = 1; 4 filled triangles for n = 2; and 13 filled triangles for n = 3; and so forth.
API specification. When writing your program, exercise modular design by organizing it into four functions, as specified in the following API:
public class Sierpinski {
// Height of an equilateral triangle whose sides are of the specified length.
public static double height(double length)
// Draws a filled equilateral triangle whose bottom vertex is (x, y)
// of the specified side length.
public static void filledTriangle(double x, double y, double length)
// Draws a Sierpinski triangle of order n, such that the largest filled
// triangle has bottom vertex (x, y) and sides of the specified length.
public static void sierpinski(int n, double x, double y, double length)
// Takes an integer command-line argument n;
// draws the outline of an equilateral triangle (pointed upwards) of length 1;
// whose bottom-left vertex is (0, 0) and bottom-right vertex is (1, 0); and
// draws a Sierpinski triangle of order n that fits snugly inside the outline.
public static void main(String[] args)
}
Restrictions: You may not change either the scale or size of the drawing window.
Part 3. In this part you will create a program Art.java that produces a recursive drawing of your own design. It must take one integer command-line argument n that controls the depth of recursion. It must stay within the drawing window when n is between 1 and 7. It can be a geometric pattern, a random construction, or anything else that takes advantage of recursive functions. For full marks, it must not be something that could be easily rewritten to use loops in place of recursion, and some aspects of the recursive function-call tree (or how parameters or overlapping are used) must be distinct from the in-class examples (HTree, Sierpinski, NestedCircles, Brownian).
Optionally, you may use the Transform2D library you implemented in Part 1. You may also define additional geometric transforms in Art.java, such as sheer, reflect across the x– or y- axis, or rotate about an arbitrary point.
Additional requirements: Your program must be organized into at least three separate functions, including main(). All functions except main() must be private.
Restrictions: You may not change the size of the drawing window (but you may change the scale). Do not add sound.
Submission. Submit Transform2D.java, Sierpinski.java, and Art.java. If your Art.java requires any supplementary image files, submit them as well. Finally, submit a readme.txt file and answer the questions therein.
Challenge for the bored. Write a program that plots Sierpinski triangles without using recursion.
WARNING: There is no programming involved in this assignment.
Classwork:
Trace the maze solver
//********************************************************************
// Represents a maze of characters. The goal is to get from the
// top left corner to the bottom right, following a path of 1s.
//********************************************************************
public class Maze
{
private final int TRIED = 3;
private final int PATH = 7;
private int stepCount = 0;
private int[][] grid = { {1,1,1},
{1,0,1},
{0,0,1}};
1 1 1
1 0 1
0 0 1
//-----------------------------------------------------------------
// Tries to recursively follow the maze.
//-----------------------------------------------------------------
public boolean traverse (int row, int column)
{
boolean done = false;
if (valid (row, column))
{
grid[row][column] = TRIED; // this cell has been tried
if (row == grid.length-1 && column == grid[0].length-1)
done = true; // the maze is solved
else
{
done = traverse (row+1, column); // down
if (!done)
done = traverse (row, column+1); // right
if (!done)
done = traverse (row-1, column); // up
if (!done)
done = traverse (row, column-1); // left
}
if (done) // this location is part of the final path
{
grid[row][column] = PATH;
stepCount--;
}
}
return done;
}
//-----------------------------------------------------------------
// Determines if a specific location is valid.
//-----------------------------------------------------------------
private boolean valid (int row, int column)
{
boolean result = false;
stepCount++;
// check if cell is in the bounds of the matrix
if (row >= 0 && row < grid.length && column >= 0 && column < grid[row].length)
// check if cell is not blocked and not previously tried
if (grid[row][column] == 1)
result = true;
return result;
}
//-----------------------------------------------------------------
// Returns the maze as a string.
//-----------------------------------------------------------------
public String toString ()
{
String result = "\n";
for (int row=0; row < grid.length; row++)
{
for (int column=0; column < grid[row].length; column++)
result += grid[row][column] + "";
result += "\n";
}
return result;
}
}
//********************************************************************
// MazeSearch.java Author: Lewis/Loftus/Cocking
// Demonstrates recursion.
//********************************************************************
public class MazeSearch
{
//-----------------------------------------------------------------
// Creates a new maze, prints its original form, tries to
// solve it, and prints out its final form.
//-----------------------------------------------------------------
public static void main (String[] args)
{
Maze labyrinth = new Maze();
System.out.println (labyrinth);
if (labyrinth.traverse (0, 0))
System.out.println ("The maze was successfully solved!");
else
System.out.println ("There is no possible path.");
System.out.println (labyrinth);
}
}
Assignment:
1. Maze 3 by 3 solver trace
Show the rows and columns visited by the program for this maze:
1 1 1
1 0 1
0 0 1
Your answer should start like this:
(row,column)
( 0 , 0) <-- 3
( 1 , 0) <-- 3
... continue to the end... including the solved path, in other words the solution.
2. Maze 3 by 3 solver trace using stacks
Think of this part of the assignment as a mental exercise where you keep the visited locations in a stack or multiple stacks.
Show the changes in the stack(s) while going through the path. At each visit, a location is pushed into the stack.
As you go through this process keep in mind the following:
1. Is the pop function ever used?
2. What happens when it gets to the end of the maze, "row == grid.length-1 && column == grid[0].length-1"?
3. How do you keep the locations that are the solution to the maze?
NOTE: If you want to use small pieces of paper to push information into the top of the stack, I have a good number of them for you to use. Xtra credit: make a video showing the process.
Here is the trace for the 3 by 3 above:
(row,column)
( 0 , 0)
( 1 , 0)
( 2 , 0)
( 1 , 1)
( 0 , 0)
( 1 , -1)
( 0 , 1)
( 1 , 1)
( 0 , 2)
( 1 , 2)
( 2 , 2)
Know a bit about the Queen piece in a game of Chess
A solution for the “8 queens” problem
Numberphile video:
In this exercise, you will solve the classic 8-queens problem: place 8 queens on an 8-by-8 chess board so that no two queens are in the same row, column, or diagonal.
There are 8! = 40,320 ways in which no two queens are placed in the same row or column. Any permutation p[] of the integers 0 to 7 gives such a placement: put queen i in row i, column p[i]. Your program Queens_YI.java should take an integer command-line argument n and enumerate all solutions to the n-queens problem by drawing the location of the queens in ASCII like the two solutions below.
Hint: to determine whether setting
q[n] = i conflicts with q[0] through q[n-1]
if q[i] equals q[n]: two queens are placed in the same column
if q[i] – q[n] equals n – i: two queens are on same major diagonal
if q[n] – q[i] equals n – i: two queens are on same minor diagonal
What preparation do I need before beginning this assignment? Read Sections 2.1–2.3 of the textbook.
The API expects the angles to be in degrees but Java’s trigonometric functions assume the arguments are in radians. How do I convert between the two? Use Math.toRadians() to convert from degrees to radians.
What is the purpose of the copy() function in Transform2D? As noted in the assignment, the transformation methods mutate a given polygon. This means that the parallel arrays representing the polygon are altered by the transformation methods. It is often useful to save a copy of the polygon before applying a transform. For example:
// Set the x- and y-scale
StdDraw.setScale(-5.0, 5.0);
// Original polygon
double[] x = { 0, 1, 1, 0 };
double[] y = { 0, 0, 2, 1 };
// Copy of original polygon
double[] cx = Transform2D.copy(x);
double[] cy = Transform2D.copy(y);
// Rotate, translate and draw the copy
Transform2D.rotate(cx, cy, -45.0);
Transform2D.translate(cx, cy, 1.0, 2.0);
StdDraw.setPenColor(StdDraw.BLUE);
StdDraw.polygon(cx, cy);
// Draw the original polygon
StdDraw.setPenColor(StdDraw.RED);
StdDraw.polygon(x, y);
Does a polygon have to be located at the origin in order to rotate it? No. You can rotate any polygon about the origin. For example:
// Original polygon
double[] x = { 1, 2, 2, 1 };
double[] y = { 1, 1, 3, 2 };
StdDraw.setPenColor(StdDraw.RED);
StdDraw.polygon(x, y);
// Rotate polygon
// 90 degrees counterclockwise
Transform2D.rotate(x, y, 90.0);
StdDraw.setPenColor(StdDraw.BLUE);
StdDraw.polygon(x, y);
Does our code have to account for invalid arguments? No. You can assume:
the array passed to copy() is not null,
arrays passed to scale(), translate() and rotate() are not null, are the same length, and do not contain the values NaN, Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINITY.
the values for the parameters alpha, theta, dx and dy are not NaN, Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINITY.
FREQUENTLY ASKED QUESTIONS: SIERPINSKI
What is the formula for the height of an equilateral triangle of side length s?
How do I draw a filled equilateral triangle? Call the method StdDraw.filledPolygon() with appropriate arguments.
I get a StackOverflowError message even when n is a very small number like 3. What could be wrong? This means you are running out of space to store the function-call stack. Often, this error is caused by an infinite recursive loop. Have you correctly defined the base case and reduction step?
May I use different colors to draw the triangles? Yes, you may use any colors that you like to draw either the outline triangle or the filled triangles, provided it contrasts with the white background.
FREQUENTLY ASKED QUESTIONS: ART
The API checker says that I need to make my methods private. How do I do that? Use the access modifier private instead of public in the method signature. A public method can be called directly by a method in another class; a private method cannot. The only public method that you should have in Art is main().
How should I approach the artistic part of the assignment? This part is meant to be fun, but here are some guidelines in case you’re not so artistic. A very good approach is to first choose a self-referential pattern as a target output. Check out the graphics exercises in Section 2.3. Here are some of our favorite student submissions from a previous year. See also the Famous Fractals in Fractals Unleashed for some ideas. Here is a list of fractals, by Hausdorff dimension. Some pictures are harder to generate than others (and some require trigonometry); consult your preceptor for advice if you’re unsure.
What will cause me to lose points on the artistic part? We consider three things: the structure of the code; the structure of the recursive function-call tree; and the art itself.
For example, the Quadricross looks very different from the in-class examples, but the code to generate it looks extremely similar to HTree, so it is a bad choice. On the other hand, even though the Sierpinski curve eventually generates something that looks like the Sierpinski triangle, the code is very different (probably including an “angle” argument in the recursive method) and so it would earn full marks.
You must do at least two of these things to get full credit on Art.java:
call one or more Transform2D method
use different parameters than our examples: f(n, x, y, size)
use different StdDraw methods than in examples (e.g., ellipses, arcs, text)
number of recursive calls not constant per level (e.g., conditional recursion)
mutually recursive methods
multiple recursive methods
doesn’t always recur from level n to level n-1
draw between recursive calls, not just before or after all recursive calls
use recursive level for secondary purpose (e.g. level dictates color)
Contrast this with the examples Htree, Sierpinski, and NestedCircles which have very similar structures to one another.
You will also lose points if your artwork can be created just as easily without recursion (such as Factorial.java). If the recursive function-call tree for your method is a straight line, it probably falls under this category.
May I use GIF, JPG, or PNG files in my artistic creation? Yes. If so, be sure to submit them along with your other files. Make it clear in your readme.txt what part of the design is yours and what part is borrowed from the image file.
How can I call the Transform2D methods inside Art.java? You must fully qualify each method name with the Transform2D library. For example:
My function for Art.java takes several parameters, but the assignment says that I can only read in one command-line argument n. What should I do? Choose a few of the best parameter values and do something like the following:
How can I create colors that aren’t predefined in standard drawing? It requires using objects that we’ll learn about in Chapter 3. In the meantime, you can use this color guide.
POSSIBLE PROGRESS STEPS: SIERPINSKI
These are purely suggestions for how you might make progress. You do not have to follow these steps. Note that your final Sierpinski.java program should not be very long (no longer than Htree, not including comments and blank lines).
/******************************************************************************
* Compilation: javac Htree.java
* Execution: java Htree n
* Dependencies: StdDraw.java
*
* Plot an order n H-tree.
*
* % java Htree 5
*
******************************************************************************/
public class Htree {
// plot an H, centered on (x, y) of the given side length
public static void drawH(double x, double y, double size) {
// compute the coordinates of the 4 tips of the H
double x0 = x - size/2;
double x1 = x + size/2;
double y0 = y - size/2;
double y1 = y + size/2;
// draw the 3 line segments of the H
StdDraw.line(x0, y0, x0, y1); // left vertical segment of the H
StdDraw.line(x1, y0, x1, y1); // right vertical segment of the H
StdDraw.line(x0, y, x1, y); // connect the two vertical segments of the H
}
// plot an order n H-tree, centered on (x, y) of the given side length
public static void draw(int n, double x, double y, double size) {
if (n == 0) return;
drawH(x, y, size);
// compute x- and y-coordinates of the 4 half-size H-trees
double x0 = x - size/2;
double x1 = x + size/2;
double y0 = y - size/2;
double y1 = y + size/2;
// recursively draw 4 half-size H-trees of order n-1
draw(n-1, x0, y0, size/2); // lower left H-tree
draw(n-1, x0, y1, size/2); // upper left H-tree
draw(n-1, x1, y0, size/2); // lower right H-tree
draw(n-1, x1, y1, size/2); // upper right H-tree
}
// reads an integer command-line argument n and plots an order n H-tree
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
double x = 0.5, y = 0.5; // center of H-tree
double size = 0.5; // side length of H-tree
draw(n, x, y, size);
}
}
Write the (non-recursive) function height() that takes the length of the sides in an equilateral triangle as an argument and returns its height. The body of this method should be a one-liner.Test your height() function.
Write a (nonrecursive) function filledTriangle() that takes three real-valued arguments (x, y, and length), and draws a filled equilateral triangle (pointed downward) with bottom vertex at (x, y) of the specified side length.To debug and test your function, write main() so that it calls filledTriangle() a few times, with different arguments. You will be able to use this function without modification in Sierpinski.java.
Write a recursive function sierpinski() that takes four (4) arguments (n, x, y, and length) and plots a Sierpinski triangle of order n, whose largest triangle has bottom vertex (x, y) and the specified side length.
Write a recursive function sierpinski() that takes one argument n, prints the value n, and then calls itself three times with the value n-1. The recursion should stop when n becomes 0. To test this function out, write main() so that it takes an integer command-line argument n and calls sierpinski(n). Ignoring whitespace, you should get the following output when you call sierpinski() with n ranging from 0 to 5. Make sure you understand how this function works, and why it prints the numbers in the order it does.
Modify sierpinski() so that in addition to printing n, it also prints the length of the triangle to be plotted. Your function should now take two arguments: n and length. The initial call from main() should be to sierpinski(n, 0.5) since the largest triangle has side length 0.5. Each successive level of recursion halves the length. Ignoring whitespace, your function should produce the following output.
Modify sierpinski() so that it takes four (4) arguments (n, x, y, and length) and plots a Sierpinski triangle of order n, whose largest triangle has bottom vertex (x, y) and the specified side length. Start by drawing Sierpinski triangles with pencil and paper. Use the picture in the Q+A above to figure out the geometry of where the smaller Sierpinski triangles should go.
Remove all print statements before submitting.
REVIEWING YOUR PROGRAM
Transform2D.java: The main must call each of the methods defined by the Transform2D API.
Sierpinski.java: Do not call StdDraw.save(), StdDraw.setCanvasSize(), StdDraw.setXscale(), StdDraw.setYscale(), or StdDraw.setScale(). These method calls interfere with grading. (However, changing the x– or y-scales in Transform2D.java and Art.java is permitted.)
Art.java: Must take exactly one integer command-line argument n (which will be between 1 and 7).
Be sure to include a comment just above each method definition explaining what the method does—this will be required in all future assignments as well. Leaving a comment for main() is not required since the header already does basically the same thing.
Continue to follow the style guidelines from the assignment FAQ.
Fractal dimension (optional diversion). In grade school, you learn that the dimension of a line segment is 1, the dimension of a square is 2, and the dimension of a cube is 3. But you probably didn’t learn what is really meant by the term dimension. How can we express what it means mathematically or computationally? Formally, we can define the Hausdorff dimension or similarity dimension of a self-similar figure by partitioning the figure into a number of self-similar pieces of smaller size. We define the dimension to be the log (# self similar pieces) / log (scaling factor in each spatial direction). For example, we can decompose the unit square into 4 smaller squares, each of side length 1/2; or we can decompose it into 25 squares, each of side length 1/5. Here, the number of self-similar pieces is 4 (or 25) and the scaling factor is 2 (or 5). Thus, the dimension of a square is 2 since log (4) / log(2) = log (25) / log (5) = 2. We can decompose the unit cube into 8 cubes, each of side length 1/2; or we can decompose it into 125 cubes, each of side length 1/5. Therefore, the dimension of a cube is log(8) / log (2) = log(125) / log(5) = 3.We can also apply this definition directly to the (set of white points in) Sierpinski triangle. We can decompose the unit Sierpinski triangle into 3 Sierpinski triangles, each of side length 1/2. Thus, the dimension of a Sierpinski triangle is log (3) / log (2) ≈ 1.585. Its dimension is fractional—more than a line segment, but less than a square! With Euclidean geometry, the dimension is always an integer; with fractal geometry, it can be something in between. Fractals are similar to many physical objects; for example, the coastline of Britain resembles a fractal; its fractal dimension has been measured to be approximately 1.25.
The great tree-list recursion problem. A binary search tree and a circular doubly linked list are conceptually built from the same type of nodes – a data field and two references to other nodes.
Hint: create a circularly linked list A from the left subtree, a circularly linked list B from the right subtree, and make the root a one-node circularly linked list. Then merge the three lists.
Implementing Comparable amounts to defining a compareTo() method that implements a natural ordering for the type.
There are many applications where we want to use different orders for the objects that we are sorting, depending on the situation. The Java Comparator interface allows us to build multiple orders within a single class.
Insertion sorting with a Comparator
public static void sort(Object[] a, Comparator c)
{
int N = a.length;
for (int i = 1; i <; N; i++) for (int j = i; j >; 0 && less(c, a[j], a[j-1]); j--)
exch(a, j, j-1);
}
private static boolean less(Comparator c, Object v, Object w)
{ return c.compare(v, w) <; 0; }
private static void exch(Object[] a, int i, int j)
{ Object t = a[i]; a[i] = a[j]; a[j] = t; }
In typical applications, items have multiple instance variables that might need to serve as sort keys.
The sort does each compare through a callback to the compare() method in Transaction that is specified by the client code. To avoid the cost of making a new Comparator object for each sort, we could use public final instance variables to define the comparators (as Java does for CASE_INSENSITIVE_ORDER).
import java.util.Comparator;
public class Transaction
{
...
private final String who;
private final Date when;
private final double amount;
...
public static class WhoOrder implements Comparator
{
public int compare(Transaction v, Transaction w)
{ return v.who.compareTo(w.when); }
}
public static class WhenOrder implements Comparator
{
public int compare(Transaction v, Transaction w)
{ return v.when.compareTo(w.when); }
}
public static class HowMuchOrder implements Comparator
{
public int compare(Transaction v, Transaction w)
{
if (v.amount < w.amount) return -1; if (v.amount > w.amount) return +1;
return 0;
} }
}
Priority queues with comparators. The same flexibility to use comparators is also useful for priority queues. Extending our standard implementation in Algorithm 2.6 to support comparators involves the following steps:
. Import java.util.Comparator.
. Add to MaxPQ an instance variable comparator and a constructor that takes a comparator as argument and initializes comparator to that value.
. Add code to less() that checks whether comparator is null (and uses it if it is not null). For example, with these changes, you could build different priority queues with Transaction keys, using the time, place, or account number for the ordering. If you remove the Key extends Comparable phrase from MinPQ, you even can support keys with no natural order.
ALGORITHM 2.6 Heap priority queue
public class MaxPQ >
{
private Key[] pq; // heap-ordered complete binary tree
private int N = 0; // in pq[1..N] with pq[0] unused
public MaxPQ(int maxN)
{ pq = (Key[]) new Comparable[maxN+1]; }
public boolean isEmpty()
{ return N == 0; }
public int size()
{ return N; }
public void insert(Key v)
{
pq[++N] = v;
swim(N); }
public Key delMax()
{
Key max = pq[1];
exch(1, N--);
pq[N+1] = null;
sink(1);
return max; }
// Retrieve max key from top.
// Exchange with last item.
// Avoid loitering.
// Restore heap property.
// Missing the implementations of these helper methods.
private boolean less(int i, int j)
private void exch(int i, int j)
private void swim(int k)
private void sink(int k)
}
Assignments:
1. Write a telephone lookup program, YI_Telephone.java. Read a data set of 1,000 names and telephone numbers from a file that contains the numbers in random order. Handle lookups by name and also reverse lookups by phone number. Use Comparator and a binary search for both lookups.
2. Write a program, YI_StringLength.java to sort an array list of strings by increasing length. Supply a Comparator.
NOTE:
Callbacks are most easily described in terms of the telephone system. A function call is analogous to calling someone on a telephone, asking her a question, getting an answer, and hanging up; adding a callback changes the analogy so that after asking her a question, you also give her your name and number so she can call you back with the answer.
http://stackoverflow.com/questions/8736378/what-is-a-callback-in-java
Dynamic shrinking. With the array implementations of stack and queue, we doubled the size of the array when it wasn’t big enough to store the next element. If we perform a number of doubling operations, and then delete a lot of elements, we might end up with an array that is much bigger than necessary. Implement the following strategy: whenever the array is 1/4 full or less, shrink it to half the size. Explain why we don’t shrink it to half the size when it is 1/2 full or less.
Stack + max. Create a data structure that efficiently supports the stack operations (pop and push) and also return the maximum element. Assume the elements are integers or reals so that you can compare them.
To consider the task of implementing iteration, we start with a snippet of client code that prints all of the items in a collection of strings, one per line:
Stack collection = new Stack();
...
for (String s : collection)
StdOut.println(s);
...
This foreach statement is shorthand for the following while statement:
Iterator i = collection.iterator();
while (i.hasNext()) {
String s = i.next();
StdOut.println(s);
}
To implement iteration in a collection:
Include the following import statement so that our code can refer to Java’s java.util.Iterator interface:
import java.util.Iterator;
Add the following to the class declaration, a promise to provide an iterator() method, as specified in the java.lang.Iterable interface:
implements Iterable
Implement a method iterator() that returns an object from a class that implements the Iterator interface:
public Iterator iterator() {
return new ListIterator();
}
Implement a nested class that implements the Iterator interface by including the methods hasNext(), next(), and remove(). We always use an empty method for the optional remove() method because interleaving iteration with operations that modify the data structure is best avoided.
The nested class ListIterator in Bag.java illustrates how to implement a class that implements the Iterator interface when the underlying data structure is a linked list.
The nested class ArrayIterator in ResizingArrayBag.java does the same when the underlying data structure is an array.
Assignments:
Implement the ADT Set, Set_YI.java with the methods below. The Set ADT uses a LinkedList structure. In mathematics, a Set is a well-defined collection of distinct objects, considered as an object in its own right. In this implementation of Set, the Set ADT behaves like a LinkedList but it doesn’t allow duplicates. Create a Node class.
add(E e)
Ensures that this collection contains the specified element.
addAll(collection<?> c)
Adds all of the elements in the specified collection to this set if they’re not already present. The alternate version is to add all elements from Set_YI.
void clear()
Removes all of the elements from this set (optional operation).
boolean contains(Object o)
Returns true if this set contains the specified element.
boolean containsAll(collection<?> c)
Returns true if this set contains all of the elements of the specified collection.
boolean equals(Object o)
Compares the specified object with this set for equality. The alternate version is to compare objects of Set_YI.
boolean isEmpty()
Returns true if this set contains no elements.
Iterator<E> iterator()
Returns an iterator over the elements in this set.
boolean remove(Object o)
Removes the specified element from this set if it is present (optional operation).
boolean removeAll(collection<?> c) Removes from this set all of its elements that are contained in the specified collection (optional operation). The ? could be whatever you choose.
int size()
Returns the number of elements in this set (its cardinality).
Know a bit about the Queen piece in a game of Chess
A solution for the “8 queens” problem
Numberphile video:
You can have access to all the Lynda.com resources with your own Princeton Public Library card.
The problem: Design and implement a recursive program that solves the Non- Attacking Queens problem. That is, write a program to determine how eight queens can be positioned on an eight-by-eight chessboard so that none of them are in the same row, column, or diagonal as any other queen. There are no other chess pieces on the board.
Assignment:
If you already implemented the solution to the problem, answer the following questions:
How does your implementation compare to the one below?
Is your implementation better than this one?
What is the time complexity (for now we can say the big-O notation)?
If you have not implemented yet, do the following:
Trace the code for 4 queens. It only has 2 solutions but 1 unique.
Explain how the implementation works
What is the time complexity (for now we can say the big-O notation)?
//********************************************************************
//
// A recursive program that solves the Non-attacking Queens problem.
//********************************************************************
public class NonAttackingQueens {
int[] queens; // Queen i is always placed in row i. The
// column is variable.
// queens[i] represents the column of the ith row
// where the ith queen is
final int NUM_QUEENS = 8;
public NonAttackingQueens()
{
queens = new int[NUM_QUEENS];
}
//-----------------------------------------------------------------
// Returns true if a queen queenNumber can be placed in column
//-----------------------------------------------------------------
boolean canPlace(int queenNumber, int column)
{
for (int row = 0; row < queenNumber; row++) // check all rows above queenNumber row
{
if (queens[row] == column) // in the same column
return false;
if (Math.abs(queens[row] - column) == Math.abs(row - queenNumber)) // same diagonal
return false;
}
return true;
}
//-----------------------------------------------------------------
// Starting with the row represented by queenNumber, find all correct
// placements in the row and below the row.
//-----------------------------------------------------------------
public void solve(int queenNumber)
{
for (int column = 0; column < NUM_QUEENS; column++) // iterate through all columns
{
if (canPlace(queenNumber, column)) // queen can be placed in current column
{
queens[queenNumber] = column; // place queen in current column
if (queenNumber + 1 >= NUM_QUEENS) // solved
printSolution();
else // keep looking
solve(queenNumber + 1);
}
}
}
//-----------------------------------------------------------------
// Computes and displays all solutions to the problem
//-----------------------------------------------------------------
public void showSolutions()
{
solve(0); // start with the first row
}
//-----------------------------------------------------------------
// Prints a grid showing the position of the queens on the chessboard.
// Queen = X
// Empty space = O
//-----------------------------------------------------------------
private void printSolution()
{
int column;
for (int row=0; row<num_queens; row++)="" {="" for="" (column="0;" column<num_queens;="" column++)="" if="" (queens[row]="=" column)="" system.out.print("="" x");="" else="" 0");="" system.out.print("\n");="" }="" system.out.println("\n-----------------------");="" public="" static="" void="" main="" (string="" args[])="" new="" nonattackingqueens().showsolutions();="" <="" pre=""></num_queens;>