tags:

views:

76

answers:

4

Hi,

I have written a method in Ruby to find all the circular combination of a text

x = "ABCDE"
(x.length).times do
  puts x
  x = x[1..x.length] + x[0].chr
end

Is there a better way to implement this ?

+7  A: 

Here's an alternative approach.

str = "ABCDE"
(0...str.length).collect { |i| (str * 2)[i, str.length] }

I used a range and #collect with the assumption that you'll want to do something else with the strings (not just print them).

wuputah
Perfect!! This is exactly wat I was looking for..
Bragboy
`(str * 2)[i, str.length]` took me a few to get my heard around. But then I realized it was genius. Nice solution!
Squeegy
+3  A: 

I would do something like this:

x = "ABCDE"
x.length.downto(0) do |i|
  puts x[i..-1] + x[0...i]
end

It concatenates the string from the current index to the end, with the begining to the current index.

This way you don't need to alter your original variable at all.

Squeegy
Thanks Squeegy, I liked your solution too!
wuputah
+2  A: 

Combine the string to itself and get all consecutive elements of size n (n is length of original string) using Enumerable.each_cons.

s = "hello"
(s + s).split('').each_cons(s.size).map(&:join)[0..-2]

# ["hello", "elloh", "llohe", "lohel", "ohell"]
Anurag
Vijay Dev
thanks @Vijay, that's a good optimization
Anurag
+2  A: 

You could write an enumerator.

#!/usr/bin/env ruby

class String
  def rotations
    Enumerator.new do|y|
      times = 0
      chars = split('')

      begin
        y.yield chars.join('')

        chars.push chars.shift
        times += 1
      end while times < chars.length
    end
  end
end

That way you can do things like this.

"test".rotations.each {|r| puts r}
AboutRuby