Percolation/Site percolation: Difference between revisions

→‎{{header|11l}}: make PercolatedException a non-fatal exception
(Add Factor example)
(→‎{{header|11l}}: make PercolatedException a non-fatal exception)
(17 intermediate revisions by 9 users not shown)
Line 18:
 
Show all output on this page.
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">UInt32 seed = 0
F nonrandom()
:seed = 1664525 * :seed + 1013904223
R Int(:seed >> 16) / Float(FF'FF)
 
V (M, nn, t) = (15, 15, 100)
 
V cell2char = ‘ #abcdefghijklmnopqrstuvwxyz’
V NOT_VISITED = 1
 
T PercolatedException
(Int, Int) t
 
F (t)
.t = t
 
F newgrid(p)
R (0 .< :nn).map(n -> (0 .< :M).map(m -> Int(nonrandom() < @@p)))
 
F pgrid(cell, percolated)
L(n) 0 .< :nn
print(‘#.) ’.format(n % 10)‘’(0 .< :M).map(m -> :cell2char[@cell[@n][m]]).join(‘ ’))
I percolated != (-1, -1)
V where = percolated[0]
print(‘!) ’(‘ ’ * where)‘’:cell2char[cell[:nn - 1][where]])
 
F walk_maze(m, n, &cell, indx) X(PercolatedException) -> N
cell[n][m] = indx
I n < :nn - 1 & cell[n + 1][m] == :NOT_VISITED
walk_maze(m, n + 1, &cell, indx)
E I n == :nn - 1
X PercolatedException((m, indx))
I m & cell[n][m - 1] == :NOT_VISITED
walk_maze(m - 1, n, &cell, indx)
I m < :M - 1 & cell[n][m + 1] == :NOT_VISITED
walk_maze(m + 1, n, &cell, indx)
I n & cell[n - 1][m] == :NOT_VISITED
walk_maze(m, n - 1, &cell, indx)
 
F check_from_top(&cell) -> (Int, Int)?
V (n, walk_index) = (0, 1)
L(m) 0 .< :M
I cell[n][m] == :NOT_VISITED
walk_index++
walk_maze(m, n, &cell, walk_index)
X.handle PercolatedException ex
R ex.t
R N
 
V sample_printed = 0B
[Float = Int] pcount
L(p10) 11
V p = p10 / 10.0
pcount[p] = 0
L(tries) 0 .< t
V cell = newgrid(p)
(Int, Int)? percolated = check_from_top(&cell)
I percolated != N
pcount[p]++
I !sample_printed
print("\nSample percolating #. x #., p = #2.2 grid\n".format(M, nn, p))
pgrid(cell, percolated)
sample_printed = 1B
print("\n p: Fraction of #. tries that percolate through\n".format(t))
 
L(p, c) sorted(pcount.items())
print(‘#.1: #.’.format(p, c / Float(t)))</syntaxhighlight>
 
{{out}}
<pre>
 
Sample percolating 15 x 15, p = 0.50 grid
 
0) a a a b b b c d # #
1) a a a a b b b d d # #
2) a b b # d # #
3) # # # # d #
4) # # # # # d d d # # #
5) # # # d # # #
6) # # # d # #
7) # # # d d # # #
8) # # d # # #
9) # # d # # # # #
0) # # # d # # #
1) # # # # d d d d # #
2) # # d d # #
3) # # # # # d # # #
4) # # # d # # # #
!) d
 
p: Fraction of 100 tries that percolate through
 
0.0: 0
0.1: 0
0.2: 0
0.3: 0
0.4: 0
0.5: 0.15
0.6: 0.57
0.7: 0.94
0.8: 1
0.9: 1
1.0: 1
</pre>
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 84 ⟶ 192:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 118 ⟶ 226:
</pre>
{{trans|D}}
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <time.h>
Line 236 ⟶ 344:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>Percolating sample (15x15, probability = 0.40):
Line 269 ⟶ 377:
0.9 1.000
1.0 1.000</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="c++">
 
#include <iostream>
#include <vector>
#include <string>
#include <random>
#include <iomanip>
 
std::random_device random;
std::mt19937 generator(random());
std::uniform_real_distribution<double> distribution(0.0F, 1.0F);
 
class Grid {
public:
Grid(const int32_t row_count, const int32_t col_count, const double probability) {
create_table(row_count, col_count, probability);
}
 
bool percolate() {
for ( int32_t x = 0; x < (int32_t) table[0].size(); ++x ) {
if ( path_exists(x, 0) ) {
return true;
}
}
return false;
}
 
void display() const {
for ( uint64_t col = 0; col < table.size(); ++col ) {
for ( uint64_t row = 0; row < table[0].size(); ++row ) {
std::cout << " " << table[col][row];
}
std::cout << std::endl;
}
std::cout << std::endl;
}
private:
bool path_exists(const int32_t x, const int32_t y) {
if ( y < 0 || x < 0 || x >= (int32_t) table[0].size() || table[y][x].compare(FILLED) != 0 ) {
return false;
}
table[y][x] = PATH;
if ( y == (int32_t) table.size() - 1 ) {
return true;
}
return path_exists(x, y + 1) || path_exists(x + 1, y) || path_exists(x - 1, y) || path_exists(x, y - 1);
}
 
void create_table(const int32_t row_count, const int32_t col_count, const double probability) {
table.assign(row_count, std::vector<std::string>(col_count, EMPTY));
for ( int32_t col = 0; col < row_count; ++col ) {
for ( int32_t row = 0; row < col_count; ++row ) {
table[col][row] = ( distribution(generator) < probability ) ? FILLED: EMPTY;
}
}
}
 
std::vector<std::vector<std::string>> table;
inline static const std::string EMPTY = " ";
inline static const std::string FILLED = ".";
inline static const std::string PATH = "#";
};
 
int main() {
const int32_t row_count = 15;
const int32_t col_count = 15;
const int32_t test_count = 1'000;
 
Grid grid(row_count, col_count, 0.5);
grid.percolate();
grid.display();
 
std::cout << "Proportion of " << test_count << " tests that percolate through the grid:" << std::endl;
for ( double probable = 0.0; probable <= 1.0; probable += 0.1 ) {
double percolation_count = 0.0;
for ( int32_t test = 0; test < test_count; ++test ) {
Grid test_grid(row_count, col_count, probable);
if ( test_grid.percolate() ) {
percolation_count += 1.0;
}
}
const double percolation_proportion = percolation_count / test_count;
std::cout << " p = " << std::setprecision(1) <<std::fixed << probable << " : "
<< std::setprecision(4) << percolation_proportion << std::endl;
}
}
</syntaxhighlight>
{{ out }}
<pre>
# . . . . . . . . .
# . . . . . . .
# . . . . . . . . . .
# # . . . . . . .
# . . . . . . . .
# # . . . . .
. # # . . . . .
. . # . . . . . . .
. # # . . . . .
. # . . .
# . . . . . . .
. # # # . . . . .
# # # . . . . .
# # . .
# . . . . . .
 
Proportion of 1000 tests that percolate through the grid:
p = 0.0: 0.0000
p = 0.1: 0.0000
p = 0.2: 0.0000
p = 0.3: 0.0000
p = 0.4: 0.0020
p = 0.5: 0.0930
p = 0.6: 0.5330
p = 0.7: 0.9750
p = 0.8: 0.9990
p = 0.9: 1.0000
p = 1.0: 1.0000
</pre>
 
=={{header|D}}==
{{trans|Python}}
<langsyntaxhighlight lang="d">import std.stdio, std.random, std.array, std.datetime;
 
enum size_t nCols = 15,
Line 366 ⟶ 594:
writefln("\nSimulations and grid printing performed" ~
" in %3.2f seconds.", sw.peek.msecs / 1000.0);
}</langsyntaxhighlight>
{{out}}
<pre>Percolating sample (15x15, probability = 0.40):
Line 401 ⟶ 629:
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: arrays combinators combinators.short-circuit formatting
fry generalizations io kernel math math.matrices math.order
math.ranges math.vectors prettyprint random sequences ;
Line 455 ⟶ 683:
] each ;
 
MAIN: site-percolation</langsyntaxhighlight>
{{out}}
<pre>
Line 491 ⟶ 719:
 
Please see sample compilation and program execution in comments at top of program. Thank you. This example demonstrates recursion and integer constants of a specific kind.
<langsyntaxhighlight lang="fortran">
! loosely translated from python.
! compilation: gfortran -Wall -std=f2008 thisfile.f08
Line 615 ⟶ 843:
 
end program percolation_site
</syntaxhighlight>
</lang>
 
=={{header|FreeBASIC}}==
{{trans|Phix}}
<syntaxhighlight lang="freebasic">#define SOLID "#"
#define EMPTY " "
#define WET "v"
 
Dim Shared As String grid()
Dim Shared As Integer last, lastrow, m, n
 
Sub make_grid(x As Integer, y As Integer, p As Double)
m = x
n = y
Redim Preserve grid(x*(y+1)+1)
last = Len(grid)
Dim As Integer lastrow = last-n
Dim As Integer i, j
For i = 0 To x-1
For j = 1 To y
grid(1+i*(y+1)+j) = Iif(Rnd < p, EMPTY, SOLID)
Next j
Next i
End Sub
 
Function ff(i As Integer) As Boolean
If i <= 0 Or i >= last Or grid(i) <> EMPTY Then Return 0
grid(i) = WET
Return i >= lastrow Or (ff(i+m+1) Or ff(i+1) Or ff(i-1) Or ff(i-m-1))
End Function
 
Function percolate() As Integer
For i As Integer = 2 To m+1
If ff(i) Then Return 1
Next i
Return 0
End Function
 
Dim As Double p
Dim As Integer ip, i, cont
 
make_grid(15, 15, 0.55)
Print "15x15 grid:"
For i = 1 To Ubound(grid)
Print grid(i);
If i Mod 15 = 0 Then Print
Next i
 
Print !"\nrunning 10,000 tests for each case:"
For ip As Ubyte = 0 To 10
p = ip / 10
cont = 0
For i = 1 To 10000
make_grid(15, 15, p)
cont += percolate()
Next i
Print Using "p=#.#: #.####"; p; cont/10000
Next ip
Sleep</syntaxhighlight>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 731 ⟶ 1,018:
g.use(x-1, y) ||
g.use(x, y-1)
}</langsyntaxhighlight>
{{out}}
<pre>+---------------+
Line 762 ⟶ 1,049:
p=1.00, 1.0000
</pre>
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">{-# LANGUAGE OverloadedStrings #-}
import Control.Monad
import Control.Monad.Random
Line 857 ⟶ 1,145:
let v = fromIntegral density / fromIntegral densityCount ]
results = zip densities (evalRand tests g2)
mapM_ print [format ("p=" % int % "/" % int % " -> " % fixed 4) density densityCount x | (density,x) <- results]</langsyntaxhighlight>
 
{{out}}
Line 910 ⟶ 1,198:
"p=10/10 -> 1.0000"
</pre>
 
=={{header|J}}==
 
One approach:
 
<langsyntaxhighlight Jlang="j">groups=:[: +/\ 2 </\ 0 , *
ooze=: [ >. [ +&* [ * [: ; groups@[ <@(* * 2 < >./)/. +
percolate=: ooze/\.@|.^:2^:_@(* (1 + # {. 1:))
 
trial=: percolate@([ >: ]?@$0:)
simulate=: %@[ * [: +/ (2 e. {:)@trial&15 15"0@#</langsyntaxhighlight>
 
Example Statistics:
<langsyntaxhighlight Jlang="j"> ,.' P THRU';(, 100&simulate)"0 (i.%<:)11
┌────────┐
│ P THRU│
Line 937 ⟶ 1,226:
│0.9 1│
│ 1 1│
└────────┘</langsyntaxhighlight>
 
Worked sample:
 
<langsyntaxhighlight Jlang="j"> 1j1 #"1 ' .#'{~ percolate 0.6>:?15 15$0
# # # # # # # #
# # # # # # # # # # # #
Line 956 ⟶ 1,245:
. . . # . # # #
. . . . . . . # # .
. . . . . . . . # # </langsyntaxhighlight>
 
An [[Percolation/Site_percolation/J|explanation with examples]] would be somewhat longer than the implementation.
Line 962 ⟶ 1,251:
Alternative implementation (with an incompatible internal API):
 
<syntaxhighlight lang="j">
<lang J>
any =: +./
all =: *./
Line 1,005 ⟶ 1,294:
 
simulate =: 100&$: : ([ %~ [: +/ [: percolate"0 #) NB. return fraction of connected cases. Use: T simulate P
</syntaxhighlight>
</lang>
 
<pre>
Line 1,069 ⟶ 1,358:
· · · · · · · · · ·
· · · · · · · · · · · ·
</pre>
 
=={{header|Java}}==
<syntaxhighlight lang="java">
 
import java.util.concurrent.ThreadLocalRandom;
 
public final class PercolationSite {
 
public static void main(String[] aArgs) {
final int rowCount = 15;
final int colCount = 15;
final int testCount = 1_000;
Grid grid = new Grid(rowCount, colCount, 0.5);
grid.percolate();
grid.display();
System.out.println("Proportion of " + testCount + " tests that percolate through the grid:");
for ( double probable = 0.0; probable <= 1.0; probable += 0.1 ) {
int percolationCount = 0;
for ( int test = 0; test < testCount; test++) {
Grid testGrid = new Grid(rowCount, colCount, probable);
if ( testGrid.percolate() ) {
percolationCount += 1;
}
}
double percolationProportion = (double) percolationCount / testCount;
System.out.println(String.format("%s%.1f%s%.4f", " p = ", probable, ": ", percolationProportion));
}
}
 
}
 
final class Grid {
public Grid(int aRowCount, int aColCount, double aProbability) {
createGrid(aRowCount, aColCount, aProbability);
}
public boolean percolate() {
for ( int x = 0; x < table[0].length; x++ ) {
if ( pathExists(x, 0) ) {
return true;
}
}
return false;
}
public void display() {
for ( int col = 0; col < table.length; col++ ) {
for ( int row = 0; row < table[0].length; row++ ) {
System.out.print(" " + table[col][row]);
}
System.out.println();
}
System.out.println();
}
private boolean pathExists(int aX, int aY) {
if ( aY < 0 || aX < 0 || aX >= table[0].length || table[aY][aX].compareTo(FILLED) != 0 ) {
return false;
}
table[aY][aX] = PATH;
if ( aY == table.length - 1 ) {
return true;
}
return pathExists(aX, aY + 1) || pathExists(aX + 1, aY) || pathExists(aX - 1, aY) || pathExists(aX, aY - 1);
}
private void createGrid(int aRowCount, int aColCount, double aProbability) {
table = new String[aRowCount][aColCount];
for ( int col = 0; col < aRowCount; col++ ) {
for ( int row = 0; row < aColCount; row++ ) {
table[col][row] = ( RANDOM.nextFloat(1.0F) < aProbability ) ? FILLED: EMPTY;
}
}
}
private String[][] table;
private static final String EMPTY = " ";
private static final String FILLED = ".";
private static final String PATH = "#";
private static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current();
}
</syntaxhighlight>
{{ out }}
<pre>
# . .
. . # # . .
. . . # # . . . . .
. . . # # # . . . .
. . # # . . .
. . . # # . . . . .
. . # # # # . . . .
. . # . . . . .
. . . # # . . . . . .
. # . . . .
. . # . . . .
. # # . . . . .
# . . . . . .
. . # . . . . . . .
. . # . . . . . . .
 
Proportion of 1000 tests that percolate through the grid:
p = 0.0: 0.0000
p = 0.1: 0.0000
p = 0.2: 0.0000
p = 0.3: 0.0000
p = 0.4: 0.0060
p = 0.5: 0.1040
p = 0.6: 0.5670
p = 0.7: 0.9480
p = 0.8: 1.0000
p = 0.9: 1.0000
p = 1.0: 1.0000
</pre>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
{{trans|Python}}
<syntaxhighlight lang="julia">using Printf, Distributions
 
<lang julia>using Distributions
 
newgrid(p::Float64, M::Int=15, N::Int=15) = rand(Bernoulli(p), M, N)
Line 1,149 ⟶ 1,554:
for (pi, fi) in zip(p, f)
@printf("p = %.1f ⇛ f = %.3f\n", pi, fi)
end</langsyntaxhighlight>
 
{{out}}
Line 1,187 ⟶ 1,592:
=={{header|Kotlin}}==
{{trans|C}}
<langsyntaxhighlight lang="scala">// version 1.2.10
 
import java.util.Random
Line 1,253 ⟶ 1,658:
println("p = %.1f: %.4f".format(p, cnt / 10000.0))
}
}</langsyntaxhighlight>
 
Sample output:
Line 1,287 ⟶ 1,692:
p = 1.0: 1.0000
</pre>
 
=={{header|Nim}}==
{{trans|Go}}
<syntaxhighlight lang="nim">import random, sequtils, strformat, strutils
 
type Grid = seq[string] # Row first, i.e. [y][x].
 
const
Full = '.'
Used = '#'
Empty = ' '
 
 
proc newGrid(p: float; xsize, ysize: Positive): Grid =
 
result = newSeqWith(ysize, newString(xsize))
for row in result.mitems:
for cell in row.mitems:
cell = if rand(1.0) < p: Full else: Empty
 
 
proc `$`(grid: Grid): string =
 
# Preallocate result to avoid multiple reallocations.
result = newStringOfCap((grid.len + 2) * (grid[0].len + 3))
 
result.add '+'
result.add repeat('-', grid[0].len)
result.add "+\n"
 
for row in grid:
result.add '|'
result.add row
result.add "|\n"
 
result.add '+'
for cell in grid[^1]:
result.add if cell == Used: Used else: '-'
result.add '+'
 
 
proc use(grid: var Grid; x, y: int): bool =
if y < 0 or x < 0 or x >= grid[0].len or grid[y][x] != Full:
return false # Off the edges, empty, or used.
grid[y][x] = Used
if y == grid.high: return true # On the bottom.
 
# Try down, right, left, up in that order.
result = grid.use(x, y + 1) or grid.use(x + 1, y) or
grid.use(x - 1, y) or grid.use(x, y - 1)
 
 
proc percolate(grid: var Grid): bool =
for x in 0..grid[0].high:
if grid.use(x, 0): return true
 
 
const
M = 15
N = 15
 
T = 1000
MinP = 0.0
MaxP = 1.0
ΔP = 0.1
 
 
randomize()
var grid = newGrid(0.5, M, N)
discard grid.percolate()
echo grid
echo ""
 
var p = MinP
while p < MaxP:
var count = 0
for _ in 1..T:
var grid = newGrid(p, M, N)
if grid.percolate(): inc count
echo &"p = {p:.2f}: {count / T:.4f}"
p += ΔP</syntaxhighlight>
 
{{out}}
<pre>+---------------+
|# # ### . .|
| ### #. . ...|
| # .##### . |
| ## # .. |
| ... . #... |
|.. . . ### |
| . .# . ..|
|.. .. #### |
| . . .# .. |
| . . ## . |
|. . .. #. ..|
|. .. ..# . . |
| .. . .# |
| ... .# .. |
| .. . # .. . |
+--------#------+
 
p = 0.00: 0.0000
p = 0.10: 0.0000
p = 0.20: 0.0000
p = 0.30: 0.0000
p = 0.40: 0.0020
p = 0.50: 0.1070
p = 0.60: 0.5620
p = 0.70: 0.9590
p = 0.80: 1.0000
p = 0.90: 1.0000
p = 1.00: 1.0000</pre>
 
=={{header|Perl}}==
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="perl">my $block = '▒';
my $water = '+';
my $pore = ' ';
Line 1,362 ⟶ 1,879:
}
 
print "$_\n" for @table;</langsyntaxhighlight>
{{out}}
<pre>Sample percolation at 0.65
Line 1,394 ⟶ 1,911:
p = 0.9: 1.00
p = 1.0: 1.00</pre>
 
=={{header|Perl 6}}==
{{works with|Rakudo|2017.02}}
 
<lang perl6>my $block = '▒';
my $water = '+';
my $pore = ' ';
my $grid = 15;
my @site;
 
enum Direction <DeadEnd Up Right Down Left>;
 
say 'Sample percolation at .6';
percolate(.6);
.join.say for @site;
say "\n";
 
my $tests = 1000;
say "Doing $tests trials at each porosity:";
for .1, .2 ... 1 -> $p {
printf "p = %0.1f: %0.3f\n", $p, (sum percolate($p) xx $tests) / $tests
}
 
sub infix:<deq> ( $a, $b ) { $a.defined && ($a eq $b) }
 
sub percolate ( $prob = .6 ) {
@site[0] = [$pore xx $grid];
@site[$grid + 1] = [$pore xx $grid];
 
for ^$grid X 1..$grid -> ($x, $y) {
@site[$y;$x] = rand < $prob ?? $pore !! $block
}
@site[0;0] = $water;
 
my @stack;
my $current = [0;0];
 
loop {
if my $dir = direction( $current ) {
@stack.push: $current;
$current = move( $dir, $current )
}
else {
return 0 unless @stack;
$current = @stack.pop
}
return 1 if $current[1] > $grid
}
 
sub direction( [$x, $y] ) {
(Down if @site[$y + 1][$x] deq $pore) ||
(Left if @site[$y][$x - 1] deq $pore) ||
(Right if @site[$y][$x + 1] deq $pore) ||
(Up if @site[$y - 1][$x] deq $pore) ||
DeadEnd
}
 
sub move ( $dir, @cur ) {
my ( $x, $y ) = @cur;
given $dir {
when Up { @site[--$y][$x] = $water }
when Down { @site[++$y][$x] = $water }
when Left { @site[$y][--$x] = $water }
when Right { @site[$y][++$x] = $water }
}
[$x, $y]
}
}</lang>
{{out}}
<pre>Sample percolation at .6
++++
▒▒▒+ ▒ ▒ ▒ ▒ ▒▒
▒▒++ ▒▒ ▒▒
▒+ ▒▒ ▒ ▒▒
▒▒ ▒++++▒ ▒▒
▒ ▒+▒▒+▒ ▒
▒++▒++ ▒▒▒ ▒
▒▒▒ +▒
▒▒ ▒ ▒++ ▒ ▒▒
▒▒▒▒▒▒▒+▒▒▒
▒ ▒ + ▒
▒▒ ▒+ ▒ ▒ ▒
▒ ▒ ▒▒+ ▒
▒▒ ▒ ▒++▒ ▒
▒ +▒ ▒▒ ▒▒
▒ ▒▒▒+ ▒▒ ▒
+
 
 
Doing 1000 trials at each porosity:
p = 0.1: 0.000
p = 0.2: 0.000
p = 0.3: 0.000
p = 0.4: 0.005
p = 0.5: 0.096
p = 0.6: 0.573
p = 0.7: 0.959
p = 0.8: 0.999
p = 0.9: 1.000
p = 1.0: 1.000
</pre>
 
=={{header|Phix}}==
{{trans|C}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>string grid
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
integer m, n, last, lastrow
<span style="color: #004080;">string</span> <span style="color: #000000;">grid</span>
 
<span style="color: #004080;">integer</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">last</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">lastrow</span>
enum SOLID = '#', EMPTY=' ', WET = 'v'
<span style="color: #008080;">enum</span> <span style="color: #000000;">SOLID</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'#'</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">EMPTY</span><span style="color: #0000FF;">=</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">WET</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'v'</span>
procedure make_grid(integer x, y, atom p)
m = x
<span style="color: #008080;">procedure</span> <span style="color: #000000;">make_grid</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
n = y
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x</span>
grid = repeat('\n',x*(y+1)+1)
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y</span>
last = length(grid)
<span style="color: #000000;">grid</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
lastrow = last-n
<span style="color: #000000;">last</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">grid</span><span style="color: #0000FF;">)</span>
for i=0 to x-1 do
<span style="color: #000000;">lastrow</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">last</span><span style="color: #0000FF;">-</span><span style="color: #000000;">n</span>
for j=1 to y do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
grid[1+i*(y+1)+j] = iff(rnd()<p?EMPTY:SOLID)
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">y</span> <span style="color: #008080;">do</span>
end for
<span style="color: #000000;">grid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">+</span><span style="color: #000000;">i</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">rnd</span><span style="color: #0000FF;">()<</span><span style="color: #000000;">p</span><span style="color: #0000FF;">?</span><span style="color: #000000;">EMPTY</span><span style="color: #0000FF;">:</span><span style="color: #000000;">SOLID</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
function ff(integer i) -- flood_fill
if i<=0 or i>=last or grid[i]!=EMPTY then return 0 end if
<span style="color: #008080;">function</span> <span style="color: #000000;">ff</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- flood_fill</span>
grid[i] = WET
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">0</span> <span style="color: #008080;">or</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">last</span> <span style="color: #008080;">or</span> <span style="color: #000000;">grid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">EMPTY</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return i>=lastrow or ff(i+m+1) or ff(i+1) or ff(i-1) or ff(i-m-1)
<span style="color: #000000;">grid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">WET</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">lastrow</span> <span style="color: #008080;">or</span> <span style="color: #000000;">ff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">m</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">or</span> <span style="color: #000000;">ff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">or</span> <span style="color: #000000;">ff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">or</span> <span style="color: #000000;">ff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">m</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function percolate()
for i=2 to m+1 do
<span style="color: #008080;">function</span> <span style="color: #000000;">percolate</span><span style="color: #0000FF;">()</span>
if ff(i) then return true end if
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
end for
<span style="color: #008080;">if</span> <span style="color: #000000;">ff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">true</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return false
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
procedure main()
make_grid(15,15,0.55)
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
{} = percolate()
<span style="color: #000000;">make_grid</span><span style="color: #0000FF;">(</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0.55</span><span style="color: #0000FF;">)</span>
printf(1,"%dx%d grid:%s",{15,15,grid})
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">percolate</span><span style="color: #0000FF;">()</span>
puts(1,"\nrunning 10,000 tests for each case:\n")
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%dx%d grid:%s"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span><span style="color: #000000;">grid</span><span style="color: #0000FF;">})</span>
for ip=0 to 10 do
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\nrunning 10,000 tests for each case:\n"</span><span style="color: #0000FF;">)</span>
atom p = ip/10
<span style="color: #008080;">for</span> <span style="color: #000000;">ip</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
integer count = 0
<span style="color: #004080;">atom</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ip</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span>
for i=1 to 10000 do
<span style="color: #004080;">integer</span> <span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
make_grid(15, 15, p)
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10000</span> <span style="color: #008080;">do</span>
count += percolate()
<span style="color: #000000;">make_grid</span><span style="color: #0000FF;">(</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">percolate</span><span style="color: #0000FF;">()</span>
printf(1,"p=%.1f: %6.4f\n", {p, count/10000})
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"p=%.1f: %6.4f\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">count</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10000</span><span style="color: #0000FF;">})</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
main()</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,579 ⟶ 1,998:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">from random import random
import string
from pprint import pprint as pp
Line 1,649 ⟶ 2,068:
print('\n p: Fraction of %i tries that percolate through\n' % t )
pp({p:c/float(t) for p, c in pcount.items()})</langsyntaxhighlight>
 
{{out}}
Line 1,690 ⟶ 2,109:
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">#lang racket
(require racket/require (only-in racket/fixnum for*/fxvector))
(require (filtered-in (lambda (name) (regexp-replace #rx"unsafe-" name ""))
Line 1,770 ⟶ 2,189:
((i (in-range (t))) #:when (perc-15x15-grid?! (make-15x15-grid p))) 1))
(define proportion-percolated (/ n-percolated-grids (t)))
(printf "p=~a\t->\t~a~%" p (real->decimal-string proportion-percolated 4)))</langsyntaxhighlight>
 
{{out}}
Line 1,801 ⟶ 2,220:
p=9/10 -> 1.0000
p=1 -> 1.0000</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2017.02}}
 
<syntaxhighlight lang="raku" line>my $block = '▒';
my $water = '+';
my $pore = ' ';
my $grid = 15;
my @site;
 
enum Direction <DeadEnd Up Right Down Left>;
 
say 'Sample percolation at .6';
percolate(.6);
.join.say for @site;
say "\n";
 
my $tests = 1000;
say "Doing $tests trials at each porosity:";
for .1, .2 ... 1 -> $p {
printf "p = %0.1f: %0.3f\n", $p, (sum percolate($p) xx $tests) / $tests
}
 
sub infix:<deq> ( $a, $b ) { $a.defined && ($a eq $b) }
 
sub percolate ( $prob = .6 ) {
@site[0] = [$pore xx $grid];
@site[$grid + 1] = [$pore xx $grid];
 
for ^$grid X 1..$grid -> ($x, $y) {
@site[$y;$x] = rand < $prob ?? $pore !! $block
}
@site[0;0] = $water;
 
my @stack;
my $current = [0;0];
 
loop {
if my $dir = direction( $current ) {
@stack.push: $current;
$current = move( $dir, $current )
}
else {
return False unless @stack;
$current = @stack.pop
}
return True if $current[1] > $grid
}
 
sub direction( [$x, $y] ) {
(Down if @site[$y + 1][$x] deq $pore) ||
(Left if @site[$y][$x - 1] deq $pore) ||
(Right if @site[$y][$x + 1] deq $pore) ||
(Up if @site[$y - 1][$x] deq $pore) ||
DeadEnd
}
 
sub move ( $dir, @cur ) {
my ( $x, $y ) = @cur;
given $dir {
when Up { @site[--$y][$x] = $water }
when Down { @site[++$y][$x] = $water }
when Left { @site[$y][--$x] = $water }
when Right { @site[$y][++$x] = $water }
}
[$x, $y]
}
}</syntaxhighlight>
{{out}}
<pre>Sample percolation at .6
++++
▒▒▒+ ▒ ▒ ▒ ▒ ▒▒
▒▒++ ▒▒ ▒▒
▒+ ▒▒ ▒ ▒▒
▒▒ ▒++++▒ ▒▒
▒ ▒+▒▒+▒ ▒
▒++▒++ ▒▒▒ ▒
▒▒▒ +▒
▒▒ ▒ ▒++ ▒ ▒▒
▒▒▒▒▒▒▒+▒▒▒
▒ ▒ + ▒
▒▒ ▒+ ▒ ▒ ▒
▒ ▒ ▒▒+ ▒
▒▒ ▒ ▒++▒ ▒
▒ +▒ ▒▒ ▒▒
▒ ▒▒▒+ ▒▒ ▒
+
 
 
Doing 1000 trials at each porosity:
p = 0.1: 0.000
p = 0.2: 0.000
p = 0.3: 0.000
p = 0.4: 0.005
p = 0.5: 0.096
p = 0.6: 0.573
p = 0.7: 0.959
p = 0.8: 0.999
p = 0.9: 1.000
p = 1.0: 1.000
</pre>
 
=={{header|Sidef}}==
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="ruby">class Percolate {
 
has block = '▒'
Line 1,869 ⟶ 2,390:
for p in (0.1..1 `by` 0.1) {
printf("p = %0.1f: %0.3f\n", p, tests.of { obj.percolate(p) }.sum / tests)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,906 ⟶ 2,427:
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
 
oo::class create SitePercolation {
Line 1,982 ⟶ 2,503:
puts [format "p=%.2f: %2.1f%%" $p [expr {$tot*100./$tries}]]
}
}}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,016 ⟶ 2,537:
p=0.90: 100.0%
p=1.00: 100.0%
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "random" for Random
import "./fmt" for Fmt
 
var rand = Random.new()
var RAND_MAX = 32767
var EMPTY = ""
 
var x = 15
var y = 15
var grid = List.filled((x + 1) * (y + 1) + 1, EMPTY)
var cell = 0
var end = 0
var m = 0
var n = 0
 
var makeGrid = Fn.new { |p|
var thresh = (p * RAND_MAX).truncate
m = x
n = y
grid.clear()
grid = List.filled(m + 1, EMPTY)
end = m + 1
cell = m + 1
for (i in 0...n) {
for (j in 0...m) {
var r = rand.int(RAND_MAX+1)
grid.add((r < thresh) ? "+" : ".")
end = end + 1
}
grid.add("\n")
end = end + 1
}
grid[end-1] = EMPTY
m = m + 1
end = end - m // end is the index of the first cell of bottom row
}
 
var ff // recursive
ff = Fn.new { |p| // flood fill
if (grid[p] != "+") return false
grid[p] = "#"
return p >= end || ff.call(p + m) || ff.call(p + 1) || ff.call(p - 1) ||
ff.call(p - m)
}
 
var percolate = Fn.new {
var i = 0
while (i < m && !ff.call(cell + i)) i = i + 1
return i < m
}
 
makeGrid.call(0.5)
percolate.call()
System.print("%(x) x %(y) grid:")
System.print(grid.join(""))
System.print("\nRunning 10,000 tests for each case:")
for (ip in 0..10) {
var p = ip / 10
var cnt = 0
for (i in 0...10000) {
makeGrid.call(p)
if (percolate.call()) cnt = cnt + 1
}
Fmt.print("p = $.1f: $.4f", p, cnt / 10000)
}</syntaxhighlight>
 
{{out}}
Sample run:
<pre>
15 x 15 grid:
..####.#####..#
+....####.#.++.
.#######.+..+++
+...##...+.++..
++++..+++.+..++
....++..+++.+++
+......++.+.+++
.......+++..+..
+.+....+.+..+++
+.+.+...+++..+.
.++...+.+......
..+..++++....++
+.++++.+..+..+.
.+..+.+.+......
..+..+.+.....++
 
Running 10,000 tests for each case:
p = 0.0: 0.0000
p = 0.1: 0.0000
p = 0.2: 0.0000
p = 0.3: 0.0000
p = 0.4: 0.0041
p = 0.5: 0.0918
p = 0.6: 0.5647
p = 0.7: 0.9545
p = 0.8: 0.9997
p = 0.9: 1.0000
p = 1.0: 1.0000
</pre>
 
=={{header|zkl}}==
{{trans|C}}
<langsyntaxhighlight lang="zkl">fcn makeGrid(m,n,p){
grid:=Data((m+1)*(n+1)); // first row and right edges are buffers
grid.write(" "*m); grid.write("\r");
Line 2,048 ⟶ 2,672:
cnt:=0.0; do(10000){ cnt+=percolate(makeGrid(15,15,p),15); }
"p=%.1f: %.4f".fmt(p, cnt/10000).println();
}</langsyntaxhighlight>
{{out}}
<pre>
1,463

edits