2

我从rand(1..117). 假设它打印 80。我想生成另一个比第一个数字少 20 到 20 之间的随机数,但仍然在 1 到 117 之间,即防止负数或大于 117 的数字。

例如,我可以得到 50、35、55、45、64、79、99、88、108 等。每个数字都在 1 到 117 之间,但不能低于或高于前一个数字的 20。

4

3 回答 3

8

将随机值 20 和最小值 (1) 放入数组中并确定最大值。与值 +20 和 117 类似,但您需要最小值。

这听起来比实际复杂得多:

puts r = rand(1..117)
99.times do
  puts r = rand([r-20, 1].max..[r+20, 117].min)
end
于 2018-05-17T20:57:55.333 回答
2

这是一个解决方案:

def randwalk(min, max, step)
  return enum_for(__callee__, min, max, step) unless block_given?

  yield n = rand(min..max)

  loop do
    # min=1 // n=3  // step=20 => subtract up to 2
    # min=1 // n=50 // step=20 => subtract up to 20
    from = [min - n, -step].max

    # max=100 // n=97 // step=30 => add up to 3
    # max=100 // n=50 // step=30 => add up to 30
    to = [max - n, step].min

    yield n += rand(from..to)
  end
end

randwalk(1, 117, 20).first(10) # => [90, 89, 103, 87, 106, 94, 96, 99, 97, 103]

randwalk返回一个 Ruby枚举器,它从定义的随机游走中产生与您选择的一样多的值。如果您允许它,它将永远持续下去,并且它不会“跨步”超出给定的最小值/最大值。如果您对实现或如何使用它有任何疑问,请告诉我。

于 2018-05-17T23:19:25.977 回答
2

您可以使用clamp来确保数字在给定范围内:

105.clamp(1, 117) #=> 105
120.clamp(1, 117) #=> 117
-15.clamp(1, 117) #=> 1

要生成一个随机序列,其中每个数字都在前一个数字的 ±20 范围内(并且仍在 1..117 范围内),我会使用Enumerator

random_sequence = Enumerator.new do |y|
  min = 1
  max = 117
  num = rand(min..max)
  loop do
    y << num
    num = rand((num - 20).clamp(min, max)..(num + 20).clamp(min, max))
  end
end

random_sequence.take(10)
#=> [12, 31, 50, 47, 57, 73, 66, 46, 60, 46]
于 2018-05-18T07:56:23.437 回答