My first solution takes a similar approach as FC first one but with
some caching. The sequence is only regenerated when the context has
changed:

class Random
    @@context = nil

    def initialize(ceiling, seed = nil)
        @seed = seed || srand(srand)
        @rand = Hash.new do |h,k|
            unless @@context == self
                srand(@seed)
                1.upto(@index - 1) {rand(ceiling)}
                @@context = self
            end
            h[k] = rand(ceiling)
        end
        reset
    end

    def next
        @rand[@index += 1]
    end

    def reset
        @index = 0
    end
end



I haven't had the time to give it too much thought so I'm not sure if
the following actually makes sense. The idea is to seed the random
generator for the next random number with an initial seed + object-
specific sequence number. The sequence is deterministic and mostly
random but differs from the default sequence.


class Random
    def initialize(ceiling, seed = nil)
        @seed = seed || (srand; rand(ceiling))
        @rand = Hash.new do |h,k|
            srand(@seed + k)
            h[k] = rand(ceiling)
        end
        reset
    end

    def next
        @rand[@index += 1]
    end

    def reset
        @index = 0
    end
end