Skip to content

Instantly share code, notes, and snippets.

@vderyagin
Created June 18, 2011 09:27
Show Gist options
  • Save vderyagin/1032951 to your computer and use it in GitHub Desktop.
Save vderyagin/1032951 to your computer and use it in GitHub Desktop.
Array#rotations method for Ruby
#! /usr/bin/env ruby
class Array
def rotations
enum = Enumerator.new do |yielder|
r = dup
length.times do
yielder << r
r = r.rotate
end
end
if block_given?
loop { yield enum.next }
else
enum
end
end
end
require 'minitest/autorun'
describe 'Array#rotations' do
before do
@ary = (1..9).to_a
end
it 'must return enumerator when called without block' do
@ary.rotations.must_be_instance_of Enumerator
end
it 'must generate exactly Array#length number of rotations' do
@ary.rotations.count.must_equal @ary.length
end
it 'must generate all possible rotations' do
@ary = [1, 2, 3]
rs = @ary.rotations.to_a
[[1, 2, 3],
[2, 3, 1],
[3, 1, 2]].each { |r| rs.must_include r }
end
it 'must generate rotations in order' do
@ary = [1, 2, 3]
rs = @ary.rotations
rs.next.must_equal [1, 2, 3]
rs.next.must_equal [2, 3, 1]
rs.next.must_equal [3, 1, 2]
end
it 'must raise StopIteration when #next called too many times' do
rs = @ary.rotations
@ary.size.times { rs.next } # raises nothing
lambda { (@ary.size + 1).times { rs.next } }
.must_raise StopIteration
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment