Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Algorithm 1 #3

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 131 additions & 10 deletions Percolation.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,135 @@
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.StdStats;
import edu.princeton.cs.algs4.StdStats;
import edu.princeton.cs.algs4.WeightedQuickUnionUF;

public class Percolation {
public Percolation(int n) // create n-by-n grid, with all sites blocked
public void open(int row, int col) // open site (row, col) if it is not open already
public boolean isOpen(int row, int col) // is site (row, col) open?
public boolean isFull(int row, int col) // is site (row, col) full?
public int numberOfOpenSites() // number of open sites
public boolean percolates() // does the system percolate?

public static void main(String[] args) // test client (optional)
}

// UF used for percolates test
private WeightedQuickUnionUF PercolateTest;

// UF used for connection site test
// open site in the top row
private WeightedQuickUnionUF TestFull;

// siteStatus stores every site's open or block
// true means open,false means block
private boolean[] siteStatus;

// percolation experiment's grid width and height
private int SIZE;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable is not static final (constant), then shouldn't be written in capital letters... Same for the two bellow...


// 1D of site connected to all sites in first row
private int H20_SURFACE;

// 1D of site connected to all sites in last row
private int OIL_BELOW;

// create N-by-N grid, with all sites blocked

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please could you use a javadoc like comment here
/** One line comment. */

public Percolation(int N) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please could you check that the input N is valid?

SIZE = N;

// the last two site for H20_SURFACE and OIL_BELOW
PercolateTest = new WeightedQuickUnionUF(SIZE * SIZE + 2);

// the last site is for H20_SURFACE
TestFull = new WeightedQuickUnionUF(SIZE * SIZE + 1);

H20_SURFACE = SIZE * SIZE;
OIL_BELOW = SIZE * SIZE + 1;

// initialize all site status blocked
siteStatus = new boolean[SIZE*SIZE + 2];
for (int i = 0; i < SIZE*SIZE; i++) {
siteStatus[i] = false;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed as the default value of boolean is false.


// initialize the two sites open
siteStatus[H20_SURFACE] = true;
siteStatus[OIL_BELOW] = true;

// for the UF for percolate test and the UF for test full
// connect each site in first row to H20_SURFACE
for (int i = 0; i < SIZE; i++) {
PercolateTest.union(H20_SURFACE, i);
TestFull.union(H20_SURFACE, i);
}

// only for the UF used for percolate test
// connect each site in last row to OIL_BELOW
for (int i = (SIZE-1)*SIZE; i < SIZE*SIZE; i++) {
PercolateTest.union(OIL_BELOW, i);
}

}

// open site (row i, column j) if it is not already
// i,j between 1 and N
public void open(int i, int j) {
if (!validIndex(i, j)) {
throw new IndexOutOfBoundsException("row or/and column index out of bounds");
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're repeating this pattern three times, you could extract it to a checkIndex method and just call that one...


if (!isOpen(i, j)) {
openSite(i, j);
connectAdjacentSite(i, j);
}
}

private void openSite(int i, int j) {
int idx = xyTo1D(i, j);
siteStatus[idx] = true;
}

private void connectAdjacentSite(int i, int j) {
connectTwoSite(i, j, i-1, j);
connectTwoSite(i, j, i+1, j);
connectTwoSite(i, j, i , j-1);
connectTwoSite(i, j, i , j+1);
}

private void connectTwoSite(int x1, int y1, int x2, int y2) {
if (validIndex(x2, y2)) {
if (isOpen(x2, y2)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could avoid enclosed if by using ANDed expression...

int p = xyTo1D(x1, y1);
int q = xyTo1D(x2, y2);
PercolateTest.union(p, q);
TestFull.union(p, q);
}
}
}

/** is site (row i, column j) open? */
public boolean isOpen(int i, int j) {
if (!validIndex(i, j)) {
throw new IndexOutOfBoundsException("row or/and column index out of bounds");
}
int n = xyTo1D(i, j);
return siteStatus[n];
}

/** is site (row i, column j) full? */
public boolean isFull(int i, int j) {
if (!validIndex(i, j)) {
throw new IndexOutOfBoundsException("row or/and column index out of bounds");
}
int p = xyTo1D(i, j);
return isOpen(i, j) && TestFull.connected(p, H20_SURFACE);
}

/** does the system percolate? */
public boolean percolates() {
if (SIZE == 1) return isOpen(1, 1); // used for 1x1 grid
return PercolateTest.connected(OIL_BELOW, H20_SURFACE);
}

// convert 2 dimensional(row, column) pair to 1 dimensional index

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please could you also use one line javadoc comment?

private int xyTo1D(int r, int c) {
return ((r - 1) * SIZE + c) - 1;
}

private boolean validIndex(int r, int c) {
if (r < 1 || r > SIZE || c < 1 || c > SIZE) {
return false;
}
return true;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could improve this by returning directly a boolean expression.
return r >=1 && ...

}