Last active
August 29, 2015 14:22
-
-
Save bacher09/fdb572d56f04ee1ac864 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
import Data.Array.IArray | |
import Data.Tuple (swap) | |
import System.Random | |
import Data.List (foldl') | |
data CoinType = Gold | |
| Silver | |
deriving(Show, Read, Eq, Ord, Bounded, Enum) | |
type Chest = (CoinType, CoinType) | |
chests :: Array Int Chest | |
chests = listArray (0, length posibleChests - 1) posibleChests | |
where | |
chestList = [(Gold, Gold), (Silver, Silver), (Gold, Silver)] | |
posibleChests = chestList ++ fmap swap chestList | |
pickCoins :: Int -> Chest | |
pickCoins n = chests ! n | |
randomCoins :: RandomGen g => g -> (Chest, g) | |
randomCoins g = (pickCoins i, g') | |
where | |
lims = bounds chests | |
(i, g') = randomR lims g | |
randomsCoins :: RandomGen g => g -> [Chest] | |
randomsCoins g = let (v, g') = randomCoins g | |
in v : randomsCoins g' | |
startCondition :: RandomGen g => g -> [Chest] | |
startCondition g = filter ((==Gold).fst) $ randomsCoins g | |
makeExperiment :: RandomGen g => Int -> g -> Double | |
makeExperiment count g = fromIntegral goodCount / fromIntegral count | |
where | |
exps = take count $ startCondition g | |
goodCount :: Int | |
goodCount = foldl' (\a v -> if snd v == Gold then a + 1 else a) 0 exps | |
main = makeExperiment 1000000 `fmap` getStdGen >>= print |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// node --use-strict --harmony | |
var Coin = { | |
gold: 0, | |
silver: 1 | |
} | |
var CHESTS = [ | |
[Coin.gold, Coin.gold], | |
[Coin.silver, Coin.silver], | |
[Coin.gold, Coin.silver] | |
] | |
var ALL_POSIBLE = CHESTS.concat(CHESTS.map(function(x) { | |
var t = x.slice() | |
t.reverse(); | |
return t; | |
})) | |
function rand_choice(arr) { | |
var rand_range = Math.floor(Math.random() * arr.length); | |
return arr[rand_range]; | |
} | |
function* pick_coins() { | |
for(;;) | |
yield rand_choice(ALL_POSIBLE); | |
} | |
function simulate(count) { | |
var k = 0, | |
i = 0; | |
for(let v of pick_coins()){ | |
if(v[0] != Coin.gold) | |
continue | |
if(i >= count) | |
break | |
else if (v[1] == Coin.gold) | |
k++ | |
i++; | |
} | |
return k / count; | |
} | |
console.log(simulate(2000000)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import random | |
try: | |
from itertools import ifilter | |
except ImportError: | |
# python 3 | |
ifilter = filter | |
class Coin: | |
gold = 0 | |
silver = 1 | |
CHESTS =[(Coin.gold, Coin.gold), | |
(Coin.silver, Coin.silver), | |
(Coin.gold, Coin.silver)] | |
POSIBLE_CHESTS = CHESTS + [(y, x) for x, y in CHESTS] | |
def picked_chests(): | |
while True: | |
yield random.choice(POSIBLE_CHESTS) | |
def simulate(count): | |
fun = lambda x: x[0] == Coin.gold | |
k = 0 | |
for i, v in enumerate(ifilter(fun, picked_chests())): | |
if i >= count: | |
break | |
elif v[1] == Coin.gold: | |
k += 1 | |
return float(k) / count | |
print(simulate(2000000)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate rand; | |
use rand::Rng; | |
#[derive(Debug, PartialEq)] | |
enum CoinType { | |
Gold, | |
Silver, | |
} | |
pub type Chest = (CoinType, CoinType); | |
pub struct ChestSequence<'a, R: 'a + Rng> { | |
rng: &'a mut R | |
} | |
macro_rules! posible_chests { | |
( $( ($x:expr, $y:expr) ),* ) => ( [$( ($x, $y), )* $( ($y, $x), )* ]) | |
} | |
static CHESTS : [Chest; 6] = posible_chests![ | |
(CoinType::Gold, CoinType::Gold), | |
(CoinType::Silver, CoinType::Silver), | |
(CoinType::Gold, CoinType::Silver)]; | |
impl<'a, 'b, R: Rng> Iterator for &'b mut ChestSequence<'a, R> { | |
type Item = &'b Chest; | |
fn next(&mut self) -> Option<&'b Chest> { | |
let chest = self.rng.choose(&CHESTS).unwrap(); | |
Some(chest) | |
} | |
} | |
fn picked_chests<'a, R: Rng>(rng: &'a mut R) -> ChestSequence<'a, R> { | |
ChestSequence{rng: rng} | |
} | |
fn simulate<R: Rng>(rng: &mut R, count: usize) -> f64 { | |
let mut gen = picked_chests(rng); | |
let pass = gen | |
.filter(|&x| x.0 == CoinType::Gold) | |
.take(count) | |
.fold(0, |a, i| if i.1 == CoinType::Gold {a+1} else {a}); | |
pass as f64 / count as f64 | |
} | |
fn main() { | |
let count = 100_000; | |
let mut rng = rand::thread_rng(); | |
let res = simulate(&mut rng, count); | |
println!("{}", res); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE ScopedTypeVariables #-} | |
module Main where | |
import Data.Array.IArray | |
import Data.Tuple (swap) | |
import Data.List (foldl') | |
import Control.Monad.ST | |
import Control.Monad (when) | |
import System.Random.MWC | |
import Data.STRef | |
data CoinType = Gold | |
| Silver | |
deriving(Show, Read, Eq, Ord, Bounded, Enum) | |
type Chest = (CoinType, CoinType) | |
chests :: Array Int Chest | |
chests = listArray (0, length posibleChests - 1) posibleChests | |
where | |
chestList = [(Gold, Gold), (Silver, Silver), (Gold, Silver)] | |
posibleChests = chestList ++ fmap swap chestList | |
pickCoins :: Int -> Chest | |
pickCoins n = chests ! n | |
randomCoins :: GenST s -> ST s Chest | |
randomCoins g = pickCoins `fmap` uniformR lims g | |
where | |
lims = bounds chests | |
startCondition :: GenST s -> ST s Chest | |
startCondition g = do | |
c <- randomCoins g | |
if fst c /= Gold | |
then startCondition g | |
else return c | |
makeExperiment :: forall s. Int -> GenST s -> ST s Double | |
makeExperiment count g = do | |
i <- newSTRef 0 | |
r <- newSTRef 0 | |
goodCount <- experiment i r | |
return $ fromIntegral goodCount / fromIntegral count | |
where | |
experiment :: STRef s Int -> STRef s Int -> ST s Int | |
experiment ir rr = do | |
c <- startCondition g | |
when (snd c == Gold) $ | |
modifySTRef' rr (+1) | |
i <- modifySTRef' ir (+1) >> readSTRef ir | |
if i == count | |
then readSTRef rr | |
else experiment ir rr | |
main :: IO () | |
main = withSystemRandom (makeExperiment 2000000) >>= print |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment