Reputation: 3
I have to generate a dynamically sized 2D array with a predetermined value in the first index of each sub array, three random values in each of the three following indices (each falling in a different range), and finally, a calculated total of the three random indices. Here is what I have so far.
print("Please enter the number of athletes competing in the triathalon: ")
field=gets.to_i
count=1
athlete = Array.new(5)
triathalon = Array.new(field){athlete}
triathalon.each do
athlete.each do
athlete.insert(0,count)
athlete.insert(1,rand(30..89))
athlete.insert(2,rand(90..119))
athlete.insert(3,rand(120..360))
#calculate total time per athlete
athlete.insert(4,athlete[1]+athlete[2]+athlete[3])
count+=1
end
end
Upvotes: 0
Views: 486
Reputation: 11183
One possible option is using Range and mapping the range using Enumerable#map.
For example given n = 3
athletes, basic example:
(1..n).map { |n| [n] } #=> [[1], [2], [3]]
So, adding some of your specifications to the basic example:
n = 3
res = (1..n).map do |n|
r1 = rand(30..89)
r2 = rand(90..119)
r3 = rand(120..360)
score = r1 + r2 + r3
[n, r1, r2, r3, score]
end
#=> [[1, 38, 93, 318, 449], [2, 64, 93, 259, 416], [3, 83, 93, 343, 519]]
[5,10,15].tap{ |a| a << a.sum } #=> [5, 10, 15, 30]
So you could write:
[rand(30..89), rand(90..119), rand(120..360)].tap{ |a| a << a.sum }
This allows to write a one liner (using Array#unshift):
(1..n).map { |n| [rand(30..89), rand(90..119), rand(120..360)].tap{ |a| a << a.sum }.unshift n }
Visualise the setup:
field = 3 # no user input for example
p athlete = Array.new(5) #=> [nil, nil, nil, nil, nil]
p triathalon = Array.new(field){athlete.dup} #=> [[nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil]]
NOTE athlete.dup
to avoid reference to the same object.
Once you see your objects (athlete
and triathalon
), you can realize that it is not required to iterate over the nested array, just access by index:
count=1
triathalon.each do |athlete|
athlete[0] = count
athlete[1] = rand(30..89)
athlete[2] = rand(90..119)
athlete[3] = rand(120..360)
athlete[4] = athlete[1] + athlete[2] + athlete[3]
count+=1
end
Improvement: to get rid of the counter use Enumerable#each_with_index.
Upvotes: 2