-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPercolation.java
More file actions
105 lines (86 loc) · 2.91 KB
/
Percolation.java
File metadata and controls
105 lines (86 loc) · 2.91 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
import edu.princeton.cs.algs4.WeightedQuickUnionUF;
public class Percolation {
private final WeightedQuickUnionUF grid;
private final WeightedQuickUnionUF fullness;
private final int size;
private final boolean[] open;
private final int virtualTop;
private final int virtualBot;
private int openedCount;
public Percolation(int n) {
if (n <= 0) {
throw new IllegalArgumentException();
}
size = n;
openedCount = 0;
grid = new WeightedQuickUnionUF(size * size + 2);
fullness = new WeightedQuickUnionUF(size * size + 1);
open = new boolean[size * size];
virtualTop = index(size, size) + 1;
virtualBot = index(size, size) + 2;
}
public void open(int row, int col) {
validateIndices(row, col);
int index = index(row, col);
if (isOpen(row, col)) {
return;
}
open[index] = true;
openedCount++;
// first row
if (row == 1) {
grid.union(virtualTop, index);
fullness.union(virtualTop, index);
}
// last row
if (row == size) {
grid.union(virtualBot, index);
}
// connecting left node if open
if (isValid(row, col - 1) && isOpen(row, col - 1)) {
grid.union(index(row, col - 1), index);
fullness.union(index(row, col - 1), index);
}
// connecting right node if open
if (isValid(row, col + 1) && isOpen(row, col + 1)) {
grid.union(index(row, col + 1), index);
fullness.union(index(row, col + 1), index);
}
// connecting top node if open
if (isValid(row - 1, col) && isOpen(row - 1, col)) {
grid.union(index(row - 1, col), index);
fullness.union(index(row - 1, col), index);
}
// connecting bottom node if open
if (isValid(row + 1, col) && isOpen(row + 1, col)) {
grid.union(index(row + 1, col), index);
fullness.union(index(row + 1, col), index);
}
}
public boolean isOpen(int row, int col) {
validateIndices(row, col);
return open[index(row, col)];
}
public boolean isFull(int row, int col) {
validateIndices(row, col);
return fullness.connected(index(row, col), virtualTop);
}
public int numberOfOpenSites() {
return openedCount;
}
public boolean percolates() {
return grid.connected(virtualTop, virtualBot);
}
private int index(int row, int col) {
validateIndices(row, col);
return (size * (row - 1) + col) - 1;
}
private void validateIndices(int i, int j) {
if (!isValid(i, j)) throw new IllegalArgumentException("Invalid indices provided.");
}
private boolean isValid(int i, int j) {
i -= 1;
j -= 1;
return i >= 0 && j >= 0 && i < size && j < size;
}
}