Advertisement
jules0707

Percolation

Sep 7th, 2020 (edited)
1,022
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.78 KB | None | 0 0
  1. import edu.princeton.cs.algs4.WeightedQuickUnionUF;
  2. /*
  3. ASSESSMENT SUMMARY
  4. Correctness:  38/38 tests passed
  5. Memory:       9/8 tests passed
  6. Timing:       20/20 tests passed
  7. Aggregate score: 101.25%
  8. Estimated student memory = 9.00 n^2 + 0.00 n + 192.00   (R^2 = 1.000)
  9.  */
  10. public class Percolation {
  11.     private final int n;
  12.     private final WeightedQuickUnionUF wquf;
  13.     private int numberOfOpenSites;
  14.     private boolean doesPercolate;
  15.     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
  16.  
  17.     public Percolation(int n) {
  18.         this.n = n;
  19.         if (n <= 0) {
  20.             throw new IllegalArgumentException("N must be > 0");
  21.         }
  22.         int gridSize = n * n;
  23.         siteStatus = new byte[gridSize + 1];
  24.         wquf = new WeightedQuickUnionUF(gridSize + 1);
  25.         numberOfOpenSites = 0;
  26.     }
  27.  
  28.     // this maps the grid coordinates to a site number
  29.     private int xyTo1D(int i, int j) {
  30.         validate(i, j);
  31.         return (j + n * (i - 1));
  32.     }
  33.  
  34.     private void validate(int i, int j) {
  35.         if (i <= 0 || i > n || j <= 0 || j > n) {
  36.             throw new IllegalArgumentException("indices (" + i + ","
  37.                     + j + ") are not between 1 and " + (n));
  38.         }
  39.     }
  40.  
  41.     public void open(int i, int j) {
  42.         validate(i, j);
  43.         int site = xyTo1D(i, j);
  44.  
  45.         if (siteStatus[site] == 000) { // site is closed
  46.             numberOfOpenSites++;
  47.             siteStatus[site] = 100; // open site now
  48.             if (i == 1) { // site is on top row
  49.                 siteStatus[site] = (byte) (siteStatus[site] | 110);
  50.             }
  51.             if (i == n) { // site is on bottom row
  52.                 siteStatus[site] = (byte) (siteStatus[site] | 101);
  53.             }
  54.             connectAdjacentSites(i, j);
  55.             if (siteStatus[site] == 111) {
  56.                 doesPercolate = true;
  57.             }
  58.         }
  59.     }
  60.  
  61.     private void connectAdjacentSites(int i, int j) {
  62.         int site = xyTo1D(i, j);
  63.         if (i > 1) { // connect above
  64.             unionAdjacent(i - 1, j, site);
  65.         }
  66.         if (j > 1) { // connect left
  67.             unionAdjacent(i, j - 1, site);
  68.         }
  69.         if (j < n) { // connect right
  70.             unionAdjacent(i, j + 1, site);
  71.         }
  72.         if (i < n) { // connect to below
  73.             unionAdjacent(i + 1, j, site);
  74.         }
  75.     }
  76.  
  77.     private void unionAdjacent(int iAdjacent, int jAdjacent, int site) {
  78.         int adjacent = xyTo1D(iAdjacent, jAdjacent);
  79.  
  80.         if (siteStatus[adjacent] != 000) { // adjacent is open
  81.             int rootPrevious = wquf.find(site); // previous root
  82.             int rootAdjacent = wquf.find(adjacent);
  83.             wquf.union(adjacent, site);
  84.             int rootNew = wquf.find(site); // new root
  85.             // every site contaminates the others with inclusive OR operation
  86.             byte res = (byte) (siteStatus[rootPrevious] | siteStatus[rootNew] | siteStatus[site] | siteStatus[adjacent] | siteStatus[rootAdjacent]);
  87.             siteStatus[rootNew] = res;
  88.             siteStatus[site] = res; // this allows to check if this site causes the system to percolate
  89.             siteStatus[rootPrevious] = res;
  90.             siteStatus[rootAdjacent] = res;
  91.         }
  92.     }
  93.  
  94.     public boolean isOpen(int i, int j) {
  95.         validate(i, j);
  96.         int site = xyTo1D(i, j);
  97.         return siteStatus[site] != 000;
  98.     }
  99.  
  100.     public boolean isFull(int i, int j) {
  101.         validate(i, j);
  102.         int site = xyTo1D(i, j);
  103.         return siteStatus[wquf.find(site)] >= 110;
  104.     }
  105.  
  106.     public int numberOfOpenSites() {
  107.         return numberOfOpenSites;
  108.     }
  109.  
  110.     public boolean percolates() {
  111.         return doesPercolate;
  112.     }
  113. }
  114.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement