Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import edu.princeton.cs.algs4.WeightedQuickUnionUF;
- /*
- ASSESSMENT SUMMARY
- Correctness: 38/38 tests passed
- Memory: 9/8 tests passed
- Timing: 20/20 tests passed
- Aggregate score: 101.25%
- Estimated student memory = 9.00 n^2 + 0.00 n + 192.00 (R^2 = 1.000)
- */
- public class Percolation {
- private final int n;
- private final WeightedQuickUnionUF wquf;
- private int numberOfOpenSites;
- private boolean doesPercolate;
- private byte[] siteStatus; // array of int desguised as an array of bytes. 000 closed 100 open not connected 110 connected to top 111 connected to top and bottom
- public Percolation(int n) {
- this.n = n;
- if (n <= 0) {
- throw new IllegalArgumentException("N must be > 0");
- }
- int gridSize = n * n;
- siteStatus = new byte[gridSize + 1];
- wquf = new WeightedQuickUnionUF(gridSize + 1);
- numberOfOpenSites = 0;
- }
- // this maps the grid coordinates to a site number
- private int xyTo1D(int i, int j) {
- validate(i, j);
- return (j + n * (i - 1));
- }
- private void validate(int i, int j) {
- if (i <= 0 || i > n || j <= 0 || j > n) {
- throw new IllegalArgumentException("indices (" + i + ","
- + j + ") are not between 1 and " + (n));
- }
- }
- public void open(int i, int j) {
- validate(i, j);
- int site = xyTo1D(i, j);
- if (siteStatus[site] == 000) { // site is closed
- numberOfOpenSites++;
- siteStatus[site] = 100; // open site now
- if (i == 1) { // site is on top row
- siteStatus[site] = (byte) (siteStatus[site] | 110);
- }
- if (i == n) { // site is on bottom row
- siteStatus[site] = (byte) (siteStatus[site] | 101);
- }
- connectAdjacentSites(i, j);
- if (siteStatus[site] == 111) {
- doesPercolate = true;
- }
- }
- }
- private void connectAdjacentSites(int i, int j) {
- int site = xyTo1D(i, j);
- if (i > 1) { // connect above
- unionAdjacent(i - 1, j, site);
- }
- if (j > 1) { // connect left
- unionAdjacent(i, j - 1, site);
- }
- if (j < n) { // connect right
- unionAdjacent(i, j + 1, site);
- }
- if (i < n) { // connect to below
- unionAdjacent(i + 1, j, site);
- }
- }
- private void unionAdjacent(int iAdjacent, int jAdjacent, int site) {
- int adjacent = xyTo1D(iAdjacent, jAdjacent);
- if (siteStatus[adjacent] != 000) { // adjacent is open
- int rootPrevious = wquf.find(site); // previous root
- int rootAdjacent = wquf.find(adjacent);
- wquf.union(adjacent, site);
- int rootNew = wquf.find(site); // new root
- // every site contaminates the others with inclusive OR operation
- byte res = (byte) (siteStatus[rootPrevious] | siteStatus[rootNew] | siteStatus[site] | siteStatus[adjacent] | siteStatus[rootAdjacent]);
- siteStatus[rootNew] = res;
- siteStatus[site] = res; // this allows to check if this site causes the system to percolate
- siteStatus[rootPrevious] = res;
- siteStatus[rootAdjacent] = res;
- }
- }
- public boolean isOpen(int i, int j) {
- validate(i, j);
- int site = xyTo1D(i, j);
- return siteStatus[site] != 000;
- }
- public boolean isFull(int i, int j) {
- validate(i, j);
- int site = xyTo1D(i, j);
- return siteStatus[wquf.find(site)] >= 110;
- }
- public int numberOfOpenSites() {
- return numberOfOpenSites;
- }
- public boolean percolates() {
- return doesPercolate;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement