Saved for later reference

online repository of stuff I had to google for hours to figure out – and random snippets of code

deadbeef random number generator in F#

Tags: , ,

I found the Deadbeef Random Number Generator when reading the Reddit thread “What’s the best / most interesting piece of code you’ve ever seen?” – and since I’m trying to learn F#, I figured I could try implementing it, first in an “imperative” way, then in a more functional way.

First the imperative way, a kind of naïve translation of the C code presented:

1
2
3
4
5
6
7
8
9
10
11
12
13
let mutable (deadbeef_seed:uint32) = uint32 0;
let mutable (deadbeef_beef:uint32) = uint32 0xdeadbeef;

let deadbeef_srand x =
    let oldseed = deadbeef_seed
    deadbeef_seed <- x
    deadbeef_beef <- uint32 0xdeadbeef
    oldseed

let deadbeef_rand () =
    deadbeef_seed <- (deadbeef_seed <<< 7) ^^^ ((deadbeef_seed >>> 25) + deadbeef_beef);
    deadbeef_beef <- (deadbeef_beef <<< 7) ^^^ ((deadbeef_beef >>> 25) + (uint32 0xdeadbeef));
    deadbeef_seed;

This is not very functional, with mutables and all that, so I tried again, with an implementation requiring no mutable variables:

1
2
3
4
5
6
7
8
9
let deadbeef_rand_seq seed = seq {
    let rec db_rand seed beef = seq {
        let newseed = (seed <<< 7) ^^^ ((seed >>> 25) + beef);
        let newbeef = (beef <<< 7) ^^^ ((beef >>> 25) + (uint32 0xdeadbeef));
        yield newseed
        yield! db_rand newseed newbeef
        }
    yield! db_rand seed (uint32 0xdeadbeef)
    }

…much better (at least in my opinion); implemented as a sequence of random numbers, deadbeef_rand_seq(seed).Take(10) would give you 10 random uint32s.
I’ll bet there are about 1000 other ways to make this more F#-like/more functional, so I’d love to hear about them!

Share

© 2009 Saved for later reference. All Rights Reserved.

This blog is powered by Wordpress and Magatheme by Bryan Helmig.