Created
August 13, 2008 11:25
-
-
Save sunny/5229 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
# AudreyRandom | |
# Randomly returns elements out of an enumerable, without picking previous elements. | |
# | |
# Author: Sunny Ripert - http://sunfox.org | |
# Licence: WTFPL | |
# | |
# You see, my ex-girlfriend used to blame her music player's random algorythm | |
# because it sometimes gave her a song which played just a few minutes ago. | |
# This is for you, Audrey ;). | |
# | |
# This algorithm makes sure of two things: | |
# - it will give you a previously returned element only after _all_ the | |
# other elements were returned. | |
# - it will never return the same element twice | |
# | |
# Example: | |
# | |
# letters = AudreyRandom.new([:a, :b, :c]) | |
# letters.next # => :b # could have been a, b or c | |
# letters.next # => :a # could have been a or c | |
# letters.next # => :c # could only have been c | |
# letters.next # => :a # could have been anything but c | |
class AudreyRandom | |
def initialize(enum) | |
@enum = enum.to_a | |
@prev ||= nil | |
@i = 0 | |
randomize | |
end | |
def randomize | |
size, orig, @enum = @enum.size, @enum, [] | |
@enum << orig.slice!(rand(orig.size)) until @enum.size == size | |
end | |
def next | |
initialize(@enum) if @i == @enum.size | |
elem = @enum[@i] | |
@i += 1 | |
return self.next if @prev == elem | |
@prev = elem | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment