-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPercolation.java
More file actions
129 lines (114 loc) · 3.26 KB
/
Copy pathPercolation.java
File metadata and controls
129 lines (114 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package coursera;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.WeightedQuickUnionUF;
public class Percolation {
private int size;
private int width;
private int[] status;
private WeightedQuickUnionUF uf;
private boolean percolate;
private int openSites;
// create N-by-N grid, with all sites blocked
public Percolation(int N) {
if(N<=0) {
throw new IllegalArgumentException();
}
size = N*N;
width = N;
status = new int[size];
uf = new WeightedQuickUnionUF(size);
openSites=0;
percolate=false;
for(int i=0;i<size;i++) {
if(i>=0 && i<width) {
byte b=010;//blocked,connected to top,not connected to bottom
status[i]=status[i]|2;
}
if(i>=size-width && i<size) {
status[i]=status[i]|1;
}
}
}
// open site (row i, column j) if it is not already
public void open(int i, int j) {
checkBounds(i, j);
if(isOpen(i,j)) return;
int num = ijTo1D(i, j);
status[num]= status[num]|4;
connectToOpenNeighbors(i, j);
int root=uf.find(num);
status[root]=status[num]|status[root];
// System.out.println(root+ " "+status[root]);
if(status[root]==7)
percolate=true;
openSites++;
}
// is site (row i, column j) open?
public boolean isOpen(int i, int j) {
checkBounds(i, j);
int num = ijTo1D(i, j);
return (status[num] >=4);
}
// is site (row i, column j) full?
public boolean isFull(int i, int j) {
checkBounds(i, j);
return status[uf.find(ijTo1D(i,j))]>=6;
}
// does the system percolate?
public boolean percolates() {
return percolate;
}
public int numberOfOpenSites() {
return openSites;
}
private void connectToOpenNeighbors(int i, int j) {
int index = ijTo1D(i, j);
if (j < width) attemptUnion(i, j+1, index);
if (j > 1) attemptUnion(i, j-1, index);
if (i < width) {
attemptUnion(i+1, j, index);
}
/*else {
uf.union(index, size+1);
}
*/
if (i > 1) {
attemptUnion(i-1, j, index);
}/* else {
uf.union(index, size);
}*/
}
private void attemptUnion(int i, int j, int index) {
if (isOpen(i, j)) {
int num = ijTo1D(i, j);
status[index]=status[uf.find(num)]|status[index];
uf.union(num, index);
int root=uf.find(index);
status[root]=status[index];
}
}
// converts index in ij notation to a single 1D index (zero-indexed)
private int ijTo1D(int i, int j) {
return ((i*width - width) + j) - 1;
}
private void checkBounds(int i, int j) {
if (i <= 0 || i > width) {
throw new java.lang.IllegalArgumentException("row index i out of bounds");
}
if (j <= 0 || j > width) {
throw new java.lang.IllegalArgumentException("row index i out of bounds");
}
}
public static void main(String[] args) {
Percolation perc = new Percolation(3);
perc.open(1, 2);
perc.open(2, 2);
perc.open(2, 3);
perc.open(3, 3);
boolean c = perc.isFull(1, 1);
//boolean c1 = perc.uf.connected(perc.ijTo1D(1, 1), perc.ijTo1D(2, 1));
//boolean c2 = perc.percolates();
StdOut.println(perc.numberOfOpenSites());
//StdOut.println(c1);
//StdOut.println(c2);
}