如果我有0到70之间的数字范围,我想选择五个随机数,随机数之和高于140,低于220.我想这样做直到五个随机数的总和在140..220范围内,然后显示这五个随机数。 *
这是我到目前为止所做的:
5.times {r=rand (0..70); puts "#{r}"}
或:
5.times {puts "#{[*0...70].sample}"}
答案 0 :(得分:3)
如果您需要实际数字而不是总和,请使用此单位:
nums = [*0..70].sample(5) until (140..220) === (nums || []).inject(:+)
如果可以重复数字,请改用:
nums = 5.times.collect {rand(0..70)} until (140..220) === (nums || []).inject(:+)
第二个的多行版本,没有统计错误(帽子提示samuil):
digits = []
valid = 140..220
until valid === digits.inject(:+)
digits = []
5.times { digits << rand(0..70) }
end
答案 1 :(得分:2)
答案不是很简短,但似乎很清楚,而且是红宝石式的。
e = Enumerator.new do |y|
loop do
y << 5.times.map { rand(0..70) }
end
end
e.find { |ary| (140..220).include? ary.inject(&:+) }
首先,我们定义枚举器,它返回从0..70范围随机化的批量数字。之后,使用#find
方法我们正在寻找第一个条目,它将满足(140..220)范围内的和的条件。
答案 2 :(得分:1)
纯粹的Ruby
sum = [*0..70].sample(5).inject(&:+) until (140..220) === sum
如果您使用ActiveSupport,则可以使用#sum
代替inject(&:+)
。
答案 3 :(得分:1)
只是为了好玩,这是我能提出的最具声明性的代码:
repeat { (0..70).sample(5) }.detect { |xs| xs.reduce(:+).in?(140...220) }
不存在的抽象的实现留给读者练习: - )
答案 4 :(得分:-1)
boundary = 140..220
numbers = *0..70
begin
numbers.sample( 5 ).reduce( :+ ).tap do |sum|
fail unless boundary === sum
end
rescue
retry
end
在讨论之后,我想提出一个catch
和throw
示例,which I have advocated myself recently,但这似乎不是一个合适的机会。因此,让我在没有例外情况下采用另一种方式:
class Object
def ergo; yield self end
end
numbers.ergo do |ary|
rslt = ary.sample( 5 ).reduce( :+ )
boundary === rslt ? rslt : redo
end