# rand number generator with limits in ruby

I have an array of 1000 numbers, randomly generated. 10 of those numbers must be between 0-9 (including 0 and 9), and 10 of those numbers must be between 991 and 1000 (including 991 and 1000). This is what I came up with:

arr = []
980.times do
arr << (11..989).to_a.sample
end

arr2 = []
10.times do
arr2 << rand(10)
end

arr3 = []
10.times do
arr3 << (990..1000).to_a.sample
end

arr4 = []
arr4 = arr + arr2 + arr3

arr4.shuffle


Is there a more elegant way to do this in ruby?

• Is it only 10 for ranges at the end or "at least 10"? Commented Dec 14, 2013 at 17:45

Some notes:

• Try to learn some functional programming, you shouldn't write Ruby as it were a low-level language (like C). Favor expressions over statements. My 2-cents on the matter, I hope it helps: http://www.slideshare.net/tokland/functional-programming-with-ruby-9975242

• Let me show a simple example of using FP. The first 4 lines of your code could be written like this: arr = 980.times.map { (11..989).to_a.sample }

• arr4 = []: Why? the next line assigns it to another expression.

• range.to_a.sample. That's very inefficient, better rand(range).

I'd write:

ranges = [0..9, 11..989, 990..1000]
output = ranges.flat_map do |range|
range.map { rand(range) }
end.shuffle

• I can't improve on your "I'd write:", but here's a variant: ranges.reduce([]) {|arr, range| arr + Array.new(range.size) {rand(range)}}.shuffle Commented Jan 8, 2014 at 7:54
• @CarySwoveland: Not that efficiency is important here (those are small arrays), but note that reduce with + leads to O(n^2) code. Commented Jan 8, 2014 at 9:38

Be careful at the boundaries — you didn't implement what you wanted. The output will never contain 10, and it might include 990 among the [991, 1000] range.