Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Average of large number of Dice Rolls in Haskell

In an attempt to learn Haskell better, I'm trying to write a program that displays the average value of the sum of 2 die, rolled X number of times. This is fairly simple in C, Java, Python... but I'm stuck in Haskell. Here's a naive attempt:

import System.Random

main = do
    g <- getStdGen
    let trials = 10000000
    let rolls = take trials (randomRs (2, 12) g :: [Int])
    let average = div (sum rolls) trials
    print average

For low number of trials, the program works. But when I run this code with ten million trials, I get an error:

Stack space overflow: current size 8388608 bytes.
Use `+RTS -Ksize -RTS' to increase it.

There's got to be a better way to write this program. In the C, Java, and Python versions, this is a simple task. I've looked at this post (and understand about 75% of the material), but when I adapt that code to this situation, summing a sequence of R [Int] doesn't work (and I'm not sure how to 'unwrap' the [Int]). What am I doing wrong? What's the right way? How do I reach random number enlightenment in Haskell?

Edit: in addition to the answer selected, as rtperson points out below, the modeling of 2 dice is incorrect; it should really be the sum of two independent rolls from 1 to 6.

like image 725
benson Avatar asked Dec 21 '22 09:12

benson


1 Answers

sum is no good to sum a long list, it runs in linear space. Try this strict version of sum:

sum' = foldl' (+) 0

foldl' is defined in Data.List.

EDIT More information can be found in this HaskellWiki article.

like image 149
n. 1.8e9-where's-my-share m. Avatar answered Dec 23 '22 23:12

n. 1.8e9-where's-my-share m.