How to resolve the algorithm Percolation/Bond percolation step by step in the Nim programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Percolation/Bond percolation step by step in the Nim programming language

Table of Contents

Problem Statement

Given an

M × N

{\displaystyle M\times N}

rectangular array of cells numbered

c e l l

[ 0.. M − 1 , 0.. N − 1 ]

{\displaystyle \mathrm {cell} [0..M-1,0..N-1]}

, assume

M

{\displaystyle M}

is horizontal and

N

{\displaystyle N}

is downwards. Each

c e l l

[ m , n ]

{\displaystyle \mathrm {cell} [m,n]}

is bounded by (horizontal) walls

h w a l l

[ m , n ]

{\displaystyle \mathrm {hwall} [m,n]}

and

h w a l l

[ m + 1 , n ]

{\displaystyle \mathrm {hwall} [m+1,n]}

; (vertical) walls

v w a l l

[ m , n ]

{\displaystyle \mathrm {vwall} [m,n]}

and

v w a l l

[ m , n + 1 ]

{\displaystyle \mathrm {vwall} [m,n+1]}

Assume that the probability of any wall being present is a constant

p

{\displaystyle p}

where Except for the outer horizontal walls at

m

0

{\displaystyle m=0}

and

m

M

{\displaystyle m=M}

which are always present. Simulate pouring a fluid onto the top surface (

n

0

{\displaystyle n=0}

) where the fluid will enter any empty cell it is adjacent to if there is no wall between where it currently is and the cell on the other side of the (missing) wall.
The fluid does not move beyond the horizontal constraints of the grid. The fluid may move “up” within the confines of the grid of cells. If the fluid reaches a bottom cell that has a missing bottom wall then the fluid can be said to 'drip' out the bottom at that point. Given

p

{\displaystyle p}

repeat the percolation

t

{\displaystyle t}

times to estimate the proportion of times that the fluid can percolate to the bottom for any given

p

{\displaystyle p}

. Show how the probability of percolating through the random grid changes with

p

{\displaystyle p}

going from

0.0

{\displaystyle 0.0}

to

1.0

{\displaystyle 1.0}

in

0.1

{\displaystyle 0.1}

increments and with the number of repetitions to estimate the fraction at any given

p

{\displaystyle p}

as

t

100

{\displaystyle t=100}

. Use an

M

10 , N

10

{\displaystyle M=10,N=10}

grid of cells for all cases. Optionally depict fluid successfully percolating through a grid graphically. Show all output on this page.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Percolation/Bond percolation step by step in the Nim programming language

Source code in the nim programming language

import random, sequtils, strformat, tables

type

  Cell = object
    full: bool
    right, down: bool     # True if open to the right (x+1) or down (y+1).

  Grid = seq[seq[Cell]]   # Row first, i.e. [y][x].


proc newGrid(p: float; xsize, ysize: Positive): Grid =

  result = newSeqWith(ysize, newSeq[Cell](xsize))
  for row in result.mitems:
    for x in 0..(xsize - 2):
      if rand(1.0) > p: row[x].right = true
      if rand(1.0) > p: row[x].down = true
    if rand(1.0) > p: row[xsize - 1].down = true


const
  Full = {false: "  ", true: "()"}.toTable
  HOpen = {false: "--", true: "  "}.toTable
  VOpen = {false: "|", true: " "}.toTable

proc `$`(grid: Grid): string =

  # Preallocate result to avoid multiple reallocations.
  result = newStringOfCap((grid.len + 1) * grid[0].len * 7)

  for _ in 0..grid[0].high:
    result.add '+'
    result.add HOpen[false]
  result.add "+\n"

  for row in grid:
    result.add VOpen[false]
    for cell in row:
      result.add Full[cell.full]
      result.add VOpen[cell.right]
    result.add '\n'
    for cell in row:
      result.add '+'
      result.add HOpen[cell.down]
    result.add "+\n"

  for cell in grid[^1]:
    result.add ' '
    result.add Full[cell.down and cell.full]


proc fill(grid: var Grid; x, y: Natural): bool =

  if y >= grid.len: return true     # Out the bottom.
  if grid[y][x].full: return false  # Already filled.
  grid[y][x].full = true

  if grid[y][x].down and grid.fill(x, y + 1): return true
  if grid[y][x].right and grid.fill(x + 1, y): return true
  if x > 0 and grid[y][x - 1].right and grid.fill(x - 1, y): return true
  if y > 0 and grid[y - 1][x].down and grid.fill(x, y - 1): return true


proc percolate(grid: var Grid): bool =
  for x in 0..grid[0].high:
    if grid.fill(x, 0): return true


const
  M = 10
  N = 10
  T = 1000
  MinP = 0.1
  MaxP = 0.99
  ΔP = 0.1

# Purposely don't seed for a repeatable example grid.
var grid = newGrid(0.4, M, N)
discard grid.percolate()
echo grid
echo ""

randomize()
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:.3f}"
  p += ΔP


  

You may also check:How to resolve the algorithm Pascal's triangle/Puzzle step by step in the REXX programming language
You may also check:How to resolve the algorithm Calculating the value of e step by step in the Tcl programming language
You may also check:How to resolve the algorithm Variable size/Get step by step in the Vala programming language
You may also check:How to resolve the algorithm Roman numerals/Encode step by step in the HicEst programming language
You may also check:How to resolve the algorithm Gauss-Jordan matrix inversion step by step in the 360 Assembly programming language