Anonymous user
Percolation/Site percolation: Difference between revisions
simplified and sped up haskell version
Thundergnat (talk | contribs) m (→{{header|Perl 6}}: Minor efficiency tweaks, rearrange slightly, clean up superfluous semicolons) |
(simplified and sped up haskell version) |
||
Line 674:
p=1.00, 1.0000
</pre>
=={{header|Haskell}}==
<lang haskell>{-# LANGUAGE OverloadedStrings #-}
import Control.Monad
import
import
import
import
type Field = UArray (Int, Int) Char
-- Start percolating some seepage through a field.
-- Recurse to continue percolation with
percolateR :: [(Int, Int)] -> Field -> (Field, [(Int,Int)])
percolateR [] f = (f, [])
percolateR seep f =
(concat $ fmap neighbors validSeep) ▼
validSeep = filter (\p@(x,y) -> x
neighbors p@(r,c) = [(r-1,c), (r+1,c), (r, c-1), (r, c+1)]▼
▲ ((rLo,cLo),(rHi,cHi)) = bounds f
▲ c <= cHi &&
▲ f!p == ' ') $ nub $ sort seep
in percolateR
-- Percolate a field; Return the percolated field.▼
(f // map (\p -> (p,'.')) validSeep)
percolate :: Field -> Field
percolate start =
let ((_,_),(
(final, _) = percolateR [(
in final
-- Generate a random field.
frnd <- fmap (\rv -> if rv<threshold then ' ' else '#') <$> getRandoms
return $
-- Get a list of "leaks" from the bottom of a field.
▲ else '#')
| r <- [0..rows-1], c <- [0..cols-1] ] ▼
leaks f =
in [f!(x,yHi)=='.'| x <- [xLo..xHi]]
▲leaky :: Field -> Bool
▲ ((_,cLo),(rHi,cHi)) = bounds f
-- Run test once; Return bool indicating success or failure.
oneTest :: Int -> Int -> Double -> Rand StdGen Bool
oneTest
-- Run test multple times; Return the number of tests that pass.
multiTest :: Int -> Int -> Int -> Double -> Rand StdGen Double
multiTest
let leakyCount = length $ filter
return $ fromIntegral leakyCount / fromIntegral
-- Display a field with walls and leaks.
showField :: Field -> IO ()
showField a = do
showField a = mapM_ print [ [ a!(r,c) | c <- [cLo..cHi]] | r <- [rLo..rHi]]▼
main :: IO ()
main = do
g <- getStdGen
let (startField, g2) = runRand (randomField 15 15 0.6) g▼
h = 15
putStrLn "Unpercolated field with 0.6 threshold."▼
threshold = 0.6
putStrLn ""
showField startField
putStrLn ""
putStrLn "Same field after percolation."
Line 751 ⟶ 756:
showField $ percolate startField
let testCount = 10000
densityCount = 10
putStrLn ""
putStrLn ( "Results of running percolation test
++ " times with thresholds ranging from 0/" ++ show densityCount
▲ let d = 10
++ " to " ++ show densityCount ++ "/" ++ show densityCount ++ " .")
let tests = sequence [multiTest 10000 15 15 v ▼
let densities = [0..densityCount]
let v = fromIntegral n / fromIntegral d ]▼
let results = zip ns (evalRand tests g2)▼
mapM_ print [format ("p=" % int % "/" % int % " -> " % fixed 4) n d r | (n,r) <- results]▼
▲ mapM_ print [format ("p=" % int % "/" % int % " -> " % fixed 4)
{{out}}
<pre style="font-size:80%">
Unpercolated field with 0.6 threshold.
"
"
"
"# #
"###
" ##
" ##
"
"
"#
" ## # ##"
"
" ###
"#### #
"
Same field after percolation.
"
"
"..#
"
"##
" ##
" ### #
"
"
"#
" ## #......##"
"
" ###
"#### #
" # #....#
Results of running percolation test 10000 times with thresholds ranging from 0
"p=0/10 -> 0.0000"
"p=1/10 -> 0.0000"
"p=2/10 -> 0.0000"
"p=3/10 -> 0.0000"
"p=4/10 -> 0.
"p=5/10 -> 0.
"p=6/10 -> 0.
"p=7/10 -> 0.
"p=8/10 -> 0.
"p=9/10 -> 1.0000"
"p=10/10 -> 1.0000"
</pre>
=={{header|J}}==
|