Skip to content

Instantly share code, notes, and snippets.

@sunny
Created August 13, 2008 11:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sunny/5229 to your computer and use it in GitHub Desktop.
Save sunny/5229 to your computer and use it in GitHub Desktop.
#!/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