繁体   English   中英

如何生成随机数之和?

[英]How do I generate a sum of random numbers?

如果我的取值范围是0-70,则我要选择五个随机数,并且随机数的总和应大于140,然后小于220,然后这样做,直到五个随机数之和在范围140..220,然后显示这五个随机数。 *

这是我到目前为止所做的:

5.times {r=rand (0..70); puts "#{r}"}

要么:

5.times {puts "#{[*0...70].sample}"}

如果您需要实际的数字而不是总和,请使用此衬纸:

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

答案不是很简短,但是看起来很清晰,并且是红宝石风格的。

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)范围内的求和条件。

用纯红宝石

sum = [*0..70].sample(5).inject(&:+) until (140..220) === sum

如果使用ActiveSupport,则可以使用#sum代替inject(&:+)

只是为了好玩,这是我能想到的最具说明性的代码:

repeat { (0..70).sample(5) }.detect { |xs| xs.reduce(:+).in?(140...220) }

不存在的抽象的实现留给读者练习:-)

boundary = 140..220
numbers = *0..70
begin
  numbers.sample( 5 ).reduce( :+ ).tap do |sum|
    fail unless boundary === sum
  end
rescue
  retry
end

经讨论后,我想在一个扔catchthrow例子, 这是我最近主张自己 ,但是这在某种程度上似乎并没有成为合适的机会。 因此,让我提出另一种无例外的做法:

class Object
  def ergo; yield self end
end

numbers.ergo do |ary|
  rslt = ary.sample( 5 ).reduce( :+ )
  boundary === rslt ? rslt : redo
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM