Percolation/Site percolation: Difference between revisions

Content added Content deleted
(Added Perl example)
Line 1,199: Line 1,199:
p = 1.0: 1.0000
p = 1.0: 1.0000
</pre>
</pre>

=={{header|Perl}}==
{{trans|Perl 6}}
<lang perl>my $block = '▒';
my $water = '+';
my $pore = ' ';
my $grid = 15;
my @site;

$D{$_} = $i++ for qw<DeadEnd Up Right Down Left>;

sub deq { defined $_[0] && $_[0] eq $_[1] }

sub percolate {
my($prob) = shift || 0.6;
$site[0] = [($pore) x $grid];
for my $y (1..$grid) {
for my $x (0..$grid-1) {
$site[$y][$x] = rand() < $prob ? $pore : $block;
}
}
$site[$grid + 1] = [($pore) x $grid];
$site[0][0] = $water;

my $x = 0;
my $y = 0;
my @stack;

while () {
if (my $dir = direction($x,$y)) {
push @stack, [$x,$y];
($x,$y) = move($dir, $x, $y)
} else {
return 0 unless @stack;
($x,$y) = @{pop @stack}
}
return 1 if $y > $grid;
}
}

sub direction {
my($x, $y) = @_;
return $D{Down} if deq($site[$y+1][$x ], $pore);
return $D{Right} if deq($site[$y ][$x+1], $pore);
return $D{Left} if deq($site[$y ][$x-1], $pore);
return $D{Up} if deq($site[$y-1][$x ], $pore);
return $D{DeadEnd};
}

sub move {
my($dir,$x,$y) = @_;
$site[--$y][ $x] = $water if $dir == $D{Up};
$site[++$y][ $x] = $water if $dir == $D{Down};
$site[ $y][ --$x] = $water if $dir == $D{Left};
$site[ $y][ ++$x] = $water if $dir == $D{Right};
$x, $y
}

my $prob = 0.65;
percolate($prob);

print "Sample percolation at $prob\n";
print join '', @$_, "\n" for @site;
print "\n";

my $tests = 100;
print "Doing $tests trials at each porosity:\n";
my @table;
for my $p (1 .. 10) {
$p = $p/10;
my $total = 0;
$total += percolate($p) for 1..$tests;
push @table, sprintf "p = %0.1f: %0.2f", $p, $total / $tests
}

print "$_\n" for @table;</lang>
{{out}}
<pre>Sample percolation at 0.65
+++
▒▒+ ▒ ▒
▒+▒▒▒ ▒▒ ▒▒ ▒
+ ▒▒▒▒▒▒
▒▒++▒ ▒▒ ▒
▒ ▒++ ▒ ▒
▒▒▒+++▒ ▒ ▒
▒ ▒▒+▒ ▒ ▒
▒ ▒+ ▒
▒ ▒++▒▒
▒ ▒+ ▒ ▒
▒▒ ▒ ++ ▒
▒ ▒▒▒▒▒++ ▒
▒ ▒ ▒ ▒▒+ ▒
▒ ▒▒▒ + ▒▒
▒ ▒ + ▒▒
+

Doing 100 trials at each porosity:
p = 0.1: 0.00
p = 0.2: 0.00
p = 0.3: 0.00
p = 0.4: 0.01
p = 0.5: 0.10
p = 0.6: 0.51
p = 0.7: 0.89
p = 0.8: 1.00
p = 0.9: 1.00
p = 1.0: 1.00</pre>


=={{header|Perl 6}}==
=={{header|Perl 6}}==