Module:Sandbox/isaacl/Probability

local me = { }

-- quick and dirty implementation for test purposes

local fRandomSeedSet = false;

local function setRandomSeed if not fRandomSeedSet then math.randomseed(os.time+os.clock*2^16+mw.site.stats.edits*2^16) fRandomSeedSet = true; end end

-- Scales up Math.random by F, so returns a random value in the range [0, F).

function me.randomFloat(F) setRandomSeed return F*math.random end -- function me.randomFloat

--[[ Returns an integer from 0 to M-1. Uses the following algorithm in order to support values of M > the maximum value supported by Math.random(upper):

Given a range [0, M): divide it into T partitions, with T-1 partitions of size N, and the last partition holding the rest. Thus T = ceiling(M/N).

Partition 0 range:  [0, N) Partition 1 range:   [N, 2N) ... Partition T-1 range: [(T-1)*N, M)

Select a partition s = floor(math.random * M / N)

If s is within range [0, T-2]: result = s*N + floor(me.randomFloat(N)) If s == T-1:                  result = s*N + floor(me.randomFloat(M-(T-1)*N))

--]]

local defaultPartitionSize = 2^31-1

-- optional parameter: partitionSize function me.randomInt(M, partitionSize) setRandomSeed local N = defaultPartitionSize if partitionSize ~= nil then N = partitionSize end -- optimization: if M < partition size N, then no need -- to partition the output range if M < N then return math.floor(me.randomFloat(M)) end local T = math.ceil(M/N) local s = math.floor(math.random * M / N)

local result

if s ~= (T-1) then result = s * N + math.floor(me.randomFloat(N)) else result = s * N + math.floor(me.randomFloat(M-(T-1)*N)) end

return result end -- function me.randomInt

return me