math.randomseed(os.time()) local function result_pos(num, max) if num == 0 then return (max - num) + 1 else return result_pos(num - 1, max) + (max - num) + 1 end end local function memoize(fn) local t = {} return function(...) local k = table.concat({...}, ',') if not t[k] then t[k] = fn(...) end return t[k] end end local result_pos = memoize(result_pos) local function crazy_dice(n) local size = result_pos(n, n) local rand = math.random(size) for i = 0, n do if rand <= result_pos(i, n) then return i end end error() end local tally = {} local count = 100000 local sides = 30 for i = 1, count do local res = crazy_dice(sides) if not tally[res] then tally[res] = 1 else tally[res] = tally[res] + 1 end end for i = 0, sides do print(i, (tally[i] or 1) / count) end