June 2018 Update
This commit is contained in:
parent
ba8067c3b7
commit
22f33d4004
5278 changed files with 84726 additions and 14379 deletions
|
|
@ -1,9 +1,9 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ var (
|
|||
)
|
||||
|
||||
func (g *grid) String() string {
|
||||
var buf bytes.Buffer
|
||||
var buf strings.Builder
|
||||
// Don't really need to call Grow but it helps avoid multiple
|
||||
// reallocations if the size is large.
|
||||
buf.Grow((len(g.cell) + 1) * len(g.cell[0]) * 7)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,93 @@
|
|||
using Distributions
|
||||
|
||||
struct Grid
|
||||
cells::BitArray{2}
|
||||
hwall::BitArray{2}
|
||||
vwall::BitArray{2}
|
||||
end
|
||||
function Grid(p::AbstractFloat, m::Integer=10, n::Integer=10)
|
||||
cells = fill(false, m, n)
|
||||
hwall = rand(Bernoulli(p), m + 1, n)
|
||||
vwall = rand(Bernoulli(p), m, n + 1)
|
||||
vwall[:, 1] = true
|
||||
vwall[:, end] = true
|
||||
return Grid(cells, hwall, vwall)
|
||||
end
|
||||
|
||||
function Base.show(io::IO, g::Grid)
|
||||
H = (" .", " _")
|
||||
V = (":", "|")
|
||||
C = (" ", "#")
|
||||
ind = findfirst(g.cells[end, :] .& .!g.hwall[end, :])
|
||||
percolated = !iszero(ind)
|
||||
println(io, "$(size(g.cells, 1))×$(size(g.cells, 2)) $(percolated ? "Percolated" : "Not percolated") grid")
|
||||
for r in 1:size(g.cells, 1)
|
||||
println(io, " ", join(H[w+1] for w in g.hwall[r, :]))
|
||||
println(io, " $(r % 10)) ", join(V[w+1] * C[c+1] for (w, c) in zip(g.vwall[r, :], g.cells[r, :])))
|
||||
end
|
||||
println(io, " ", join(H[w+1] for w in g.hwall[end, :]))
|
||||
if percolated
|
||||
println(io, " !) ", " " ^ (ind - 1), '#')
|
||||
end
|
||||
end
|
||||
|
||||
function floodfill!(m::Integer, n::Integer, cells::AbstractMatrix{<:Integer},
|
||||
hwall::AbstractMatrix{<:Integer}, vwall::AbstractMatrix{<:Integer})
|
||||
# fill cells
|
||||
cells[m, n] = true
|
||||
percolated = false
|
||||
# bottom
|
||||
if m < size(cells, 1) && !hwall[m+1, n] && !cells[m+1, n]
|
||||
percolated = percolated || floodfill!(m + 1, n, cells, hwall, vwall)
|
||||
# The Bottom
|
||||
elseif m == size(cells, 1) && !hwall[m+1, n]
|
||||
return true
|
||||
end
|
||||
# left
|
||||
if n > 1 && !vwall[m, n] && !cells[m, n-1]
|
||||
percolated = percolated || floodfill!(m, n - 1, cells, hwall, vwall)
|
||||
end
|
||||
# right
|
||||
if n < size(cells, 2) && !vwall[m, n+1] && !cells[m, n+1]
|
||||
percolated = percolated || floodfill!(m, n + 1, cells, hwall, vwall)
|
||||
end
|
||||
# top
|
||||
if m > 1 && !hwall[m, n] && !cells[m-1, n]
|
||||
percolated = percolated || floodfill!(m - 1, n, cells, hwall, vwall)
|
||||
end
|
||||
return percolated
|
||||
end
|
||||
function pourontop!(g::Grid)
|
||||
m, n = 1, 1
|
||||
percolated = false
|
||||
while !percolated && n ≤ size(g.cells, 2)
|
||||
percolated = !g.hwall[m, n] && floodfill!(m, n, g.cells, g.hwall, g.vwall)
|
||||
n += 1
|
||||
end
|
||||
return percolated
|
||||
end
|
||||
|
||||
function main(probs, nrep::Integer=1000)
|
||||
sampleprinted = false
|
||||
pcount = zeros(Int, size(probs))
|
||||
for (i, p) in enumerate(probs), _ in 1:nrep
|
||||
g = Grid(p)
|
||||
percolated = pourontop!(g)
|
||||
if percolated
|
||||
pcount[i] += 1
|
||||
if !sampleprinted
|
||||
println(g)
|
||||
sampleprinted = true
|
||||
end
|
||||
end
|
||||
end
|
||||
return pcount ./ nrep
|
||||
end
|
||||
|
||||
probs = collect(10:-1:0) ./ 10
|
||||
percprobs = main(probs)
|
||||
|
||||
println("Fraction of 1000 tries that percolate through:")
|
||||
for (pr, pp) in zip(probs, percprobs)
|
||||
@printf("\tp = %.3f ⇒ freq. = %5.3f\n", pr, pp)
|
||||
end
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
// version 1.2.10
|
||||
|
||||
import java.util.Random
|
||||
|
||||
val rand = Random()
|
||||
const val RAND_MAX = 32767
|
||||
|
||||
// cell states
|
||||
const val FILL = 1
|
||||
const val RWALL = 2 // right wall
|
||||
const val BWALL = 4 // bottom wall
|
||||
|
||||
val x = 10
|
||||
val y = 10
|
||||
var grid = IntArray(x * (y + 2))
|
||||
var cells = 0
|
||||
var end = 0
|
||||
var m = 0
|
||||
var n = 0
|
||||
|
||||
fun makeGrid(p: Double) {
|
||||
val thresh = (p * RAND_MAX).toInt()
|
||||
m = x
|
||||
n = y
|
||||
grid.fill(0) // clears grid
|
||||
for (i in 0 until m) grid[i] = BWALL or RWALL
|
||||
cells = m
|
||||
end = m
|
||||
for (i in 0 until y) {
|
||||
for (j in x - 1 downTo 1) {
|
||||
val r1 = rand.nextInt(RAND_MAX + 1)
|
||||
val r2 = rand.nextInt(RAND_MAX + 1)
|
||||
grid[end++] = (if (r1 < thresh) BWALL else 0) or
|
||||
(if (r2 < thresh) RWALL else 0)
|
||||
}
|
||||
val r3 = rand.nextInt(RAND_MAX + 1)
|
||||
grid[end++] = RWALL or (if (r3 < thresh) BWALL else 0)
|
||||
}
|
||||
}
|
||||
|
||||
fun showGrid() {
|
||||
for (j in 0 until m) print("+--")
|
||||
println("+")
|
||||
|
||||
for (i in 0..n) {
|
||||
print(if (i == n) " " else "|")
|
||||
for (j in 0 until m) {
|
||||
print(if ((grid[i * m + j + cells] and FILL) != 0) "[]" else " ")
|
||||
print(if ((grid[i * m + j + cells] and RWALL) != 0) "|" else " ")
|
||||
}
|
||||
println()
|
||||
if (i == n) return
|
||||
for (j in 0 until m) {
|
||||
print(if ((grid[i * m + j + cells] and BWALL) != 0) "+--" else "+ ")
|
||||
}
|
||||
println("+")
|
||||
}
|
||||
}
|
||||
|
||||
fun fill(p: Int): Boolean {
|
||||
if ((grid[p] and FILL) != 0) return false
|
||||
grid[p] = grid[p] or FILL
|
||||
if (p >= end) return true // success: reached bottom row
|
||||
return (((grid[p + 0] and BWALL) == 0) && fill(p + m)) ||
|
||||
(((grid[p + 0] and RWALL) == 0) && fill(p + 1)) ||
|
||||
(((grid[p - 1] and RWALL) == 0) && fill(p - 1)) ||
|
||||
(((grid[p - m] and BWALL) == 0) && fill(p - m))
|
||||
}
|
||||
|
||||
fun percolate(): Boolean {
|
||||
var i = 0
|
||||
while (i < m && !fill(cells + i)) i++
|
||||
return i < m
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
makeGrid(0.5)
|
||||
percolate()
|
||||
showGrid()
|
||||
|
||||
println("\nrunning $x x $y grids 10,000 times for each p:")
|
||||
for (p in 1..9) {
|
||||
var cnt = 0
|
||||
val pp = p / 10.0
|
||||
for (i in 0 until 10_000) {
|
||||
makeGrid(pp)
|
||||
if (percolate()) cnt++
|
||||
}
|
||||
println("p = %3g: %.4f".format(pp, cnt.toDouble() / 10_000))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue