Skip to content

Instantly share code, notes, and snippets.

@bacher09
Last active August 29, 2015 14:22
Show Gist options
  • Save bacher09/fdb572d56f04ee1ac864 to your computer and use it in GitHub Desktop.
Save bacher09/fdb572d56f04ee1ac864 to your computer and use it in GitHub Desktop.
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
// 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));
#!/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))
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);
}
{-# 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