Percolation/Bond percolation: Difference between revisions

C++ version
(→‎{{header|zkl}}: brain dead programmer)
(C++ version)
Line 160:
p = 0.9: 0.0000
</pre>
 
=={{header|C++}}==
{{trans|C}}
<lang cpp>#include <cstdlib>
#include <iostream>
#include <string>
 
// cell states:
enum {
FILL = 1,
RWALL = 2, // right wall
BWALL = 4 // bottom wall
};
 
using namespace std;
 
class Grid {
public:
Grid(const double p, const unsigned int x, const unsigned int y) : m(x), n(y) {
const int thresh = static_cast<int>(RAND_MAX * p);
 
// Allocate two addition rows to avoid checking bounds.
// Bottom row is also required by drippage
start = new cell[m * (n + 2u)];
cells = start + m;
for (auto i = 0u; i < m; i++)
start[i] = BWALL | RWALL;
 
end = cells;
for (auto i = 0u; i < y; i++) {
for (auto j = x; --j;)
*end++ = (rand() < thresh ? BWALL : 0) | (rand() < thresh ? RWALL : 0);
*end++ = RWALL | (rand() < thresh ? BWALL : 0);
}
::memset(end, 0u, sizeof(cell) * m);
}
 
~Grid() {
delete[] start;
cells = 0;
start = 0;
end = 0;
}
 
int percolate() {
auto i = 0u;
for (; i < m && !fill(cells + i); i++);
return i < m;
}
 
void show() {
for (auto j = 0u; j < m; j++) cout << ("+--");
cout << '+' << endl;
 
for (auto i = 0u; i <= n; i++) {
cout << (i == n ? ' ' : '|');
for (auto j = 0u; j < m; j++) {
cout << ((cells[i * m + j] & FILL) ? "[]" : " ");
cout << ((cells[i * m + j] & RWALL) ? '|' : ' ');
}
cout << endl;
 
if (i == n) return;
 
for (auto j = 0u; j < m; j++)
cout << ((cells[i * m + j] & BWALL) ? "+--" : "+ ");
cout << '+' << endl;
}
}
 
private:
typedef unsigned int cell;
 
int fill(cell* p) {
if ((*p & FILL)) return 0;
*p |= FILL;
if (p >= end) return 1; // success: reached bottom row
 
return (!(p[0] & BWALL) && fill(p + m)) || (!(p[0] & RWALL) && fill(p + 1)) ||
(!(p[-1] & RWALL) && fill(p - 1)) || (!(p[0-m] & BWALL) && fill(p - m));
}
 
cell* cells;
cell* start;
cell* end;
const unsigned int m;
const unsigned int n;
};
 
 
int main() {
const auto M = 10u, N = 10u;
Grid grid(.5, M, N);
grid.percolate();
grid.show();
 
const auto C = 10000u;
cout << endl << "running " << M << "x" << N << " grids " << C << " times for each p:" << endl;
for (auto p = 1; p < M; p++) {
auto cnt = 0u, i = 0u;
for (; i < C; i++)
cnt += Grid(p / static_cast<double>(M), M, N).percolate();
cout << "p = " << p / static_cast<double>(M) << ": " << static_cast<double>(cnt) / i << endl;
}
 
return EXIT_SUCCESS;
}</lang>
 
=={{header|D}}==
Anonymous user