Reputation: 17
I'm quite new to learning ruby and I am working through Learn to Program by Chris Pine. One of the exercises he suggests to try out is that of writing a shuffle method (I am aware of the #shuffle
method). So far, I have come up with this code, which seems to do the job:
array_to_shuffle = []
puts "Give me a list of words to shuffle, press enter on an empty line for the result."
input = gets.chomp
while input != ""
array_to_shuffle = array_to_shuffle.push(input)
input = gets.chomp
end
def recursive_shuffle(array_to_shuffle, shuffled_array = [])
return shuffled_array unless array_to_shuffle.size > 0
array_size = array_to_shuffle.size()
random_number = rand(1..array_size)-1
element_transfered = array_to_shuffle [random_number]
shuffled_array = shuffled_array.push(element_transfered)
array_to_shuffle.delete(element_transfered)
recursive_shuffle(array_to_shuffle, shuffled_array)
end
puts recursive_shuffle(array_to_shuffle)
However, it is quite long-winded considering what it actually does. Is there any way I could improve on this?
Upvotes: 0
Views: 1191
Reputation: 36101
Your idea is to pick elements at random until you have picked all elements.
Other than verbosity, another issue that you have is that you use #delete
. Hence if there are two repeating elements in the array, you will get only one in the shuffled result.
Also you mutate the array passed, which is generally undesirable. Here is an implementation of the same algorithm:
def recursive_shuffle(to_shuffle, shuffled = [])
return shuffled if to_shuffle.empty?
to_shuffle = to_shuffle.dup if shuffled.empty?
element = to_shuffle.sample
to_shuffle.delete_at(to_shuffle.index(element))
recursive_shuffle(to_shuffle, shuffled + [element])
end
As for a simpler solution:
array.sort_by { rand }
Upvotes: 3