This repository was archived by the owner on Oct 13, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPercolation.java
118 lines (96 loc) · 2.66 KB
/
Percolation.java
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
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.WeightedQuickUnionUF;
public class Percolation
{
private static final String ExcpNegative = "n is not valid! must be > 0";
private static final String ExcpBounds = "site out of bound!";
private static final int ROOT_BOTTOM = 0;
private static final int ROOT_TOP = 1;
private final WeightedQuickUnionUF uf;
private final int size;
private final boolean[] open_sites;
private int n_open;
// creates n-by-n grid, with all sites initially blocked
public Percolation(int n)
{
if (n <= 0)
throw new IllegalArgumentException(ExcpNegative);
size = n;
n_open = 0;
uf = new WeightedQuickUnionUF(2 + n * n);
open_sites = new boolean[2 + n * n];
}
private int site(int row, int col)
{
if (row < 1 || size < row || col < 1 || size < col)
throw new IllegalArgumentException(ExcpBounds);
row--;
col--;
return 2 + row * size + col;
}
// opens the site (row, col) if it is not open already
public void open(int row, int col)
{
final int[] dx = {0, 0, 1, -1};
final int[] dy = {1, -1, 0, 0};
if (isOpen(row, col))
return;
int cell = site(row, col);
n_open += 1;
open_sites[cell] = true;
if (row == 1)
uf.union(ROOT_BOTTOM, cell);
if (row == size)
uf.union(ROOT_TOP, cell);
for (int i = 0; i < 4; ++i)
try {
int x = col + dx[i];
int y = row + dy[i];
int neighbor = site(y, x);
if (open_sites[neighbor])
uf.union(cell, neighbor);
} catch(IllegalArgumentException e) {
continue;
}
}
// is the site (row, col) open?
public boolean isOpen(int row, int col)
{
return open_sites[site(row, col)];
}
// is the site (row, col) full?
public boolean isFull(int row, int col)
{
if (!isOpen(row, col))
return false;
return uf.find(site(row, col)) == uf.find(ROOT_BOTTOM);
}
// returns the number of open sites
public int numberOfOpenSites()
{
return n_open;
}
// does the system percolate?
public boolean percolates()
{
return uf.find(ROOT_TOP) == uf.find(ROOT_BOTTOM);
}
// test client (optional)
public static void main(String[] args)
{
int n = StdIn.readInt();
Percolation perc = new Percolation(n);
while (!StdIn.isEmpty())
perc.open(StdIn.readInt(),
StdIn.readInt());
StdOut.println("percolates? " + perc.percolates());
StdOut.println("open_sites? " + perc.numberOfOpenSites());
while (!perc.percolates())
perc.open(StdRandom.uniform(1, n + 1),
StdRandom.uniform(1, n + 1));
StdOut.println("percolates? " + perc.percolates());
StdOut.println("open_sites? " + perc.numberOfOpenSites());
}
}