此问题可能是使用Ruby的flip-flop operator的教科书示例。
由于只有当存在非负整数steps
这样的high = low + steps * increment
时,我已经用steps
替换了方法的参数high
。
def oscillate(low, steps, increment, length)
high = low + steps * increment
n = low
length.times.each_with_object([]) do |_,a|
a << n
n += (n==low)..(n==high-increment) ? increment : -increment
end
end
oscillate(0,3,1,9)
#=> [0, 1, 2, 3, 2, 1, 0, 1, 2]
oscillate(-1, 4, 2, 16)
#=> [-1, 1, 3, 5, 7, 5, 3, 1, -1, 1, 3, 5, 7, 5, 3, 1]
为了表明这里发生了什么,我将修改代码一点,增加一些puts
语句,然后用第一个例子运行它。
def oscillate(low, steps, increment, length)
high = low + steps * increment
puts "high = #{high}"
n = low
length.times.each_with_object([]) do |_,a|
a << n
diff = (n==low)..(n==high-increment) ? increment : -increment
print "n=#{n}, a<<n=#{a}, diff=#{diff}, "
n += diff
puts "n+=diff=#{n}"
end
end
oscillate(0,3,1,9)
high = 3
n=0, a<<n=[0], diff= 1, n+=diff=1
n=1, a<<n=[0, 1], diff= 1, n+=diff=2
n=2, a<<n=[0, 1, 2], diff= 1, n+=diff=3
n=3, a<<n=[0, 1, 2, 3], diff=-1, n+=diff=2
n=2, a<<n=[0, 1, 2, 3, 2], diff=-1, n+=diff=1
n=1, a<<n=[0, 1, 2, 3, 2, 1], diff=-1, n+=diff=0
n=0, a<<n=[0, 1, 2, 3, 2, 1, 0], diff= 1, n+=diff=1
n=1, a<<n=[0, 1, 2, 3, 2, 1, 0, 1], diff= 1, n+=diff=2
n=2, a<<n=[0, 1, 2, 3, 2, 1, 0, 1, 2], diff= 1, n+=diff=3
#=> [0, 1, 2, 3, 2, 1, 0, 1, 2]
这很好,但它会重新计算每次拍摄的整个顺序。确定小序列,但我建议添加memoization,如果序列很大。 –
谢谢你的方法! – MattF
@mattf很高兴听到这是有帮助的!如果你喜欢这个答案,考虑接受它与复选标记。 – akuhn