计数阈值命中

时间:2014-08-25 17:30:25

标签: ruby loops iterator logic time-series

独自跑步并希望得到一些帮助。如果您有一系列数字并且想要计算价值跨越障碍的次数,您将如何做到这一点?

series = [1, 6, 2, 4, 1, 9, 2]
series.hit_counts(upper=7, middle=5, lower=3) #returns 3

详情

1 -> 6 = +1 (Going from 1 to 6 hits the lower and middle threshold)
6 -> 2 = +0 (The high value, 6, never reached the upper threshold although it crosses the middle)
2 -> 4 = +0 (2 is below the lower threshold but has not hit the middle)
4 -> 1 = +0 (The series still has not reached the middle threshold)
1 -> 9 = +1 (The series hit the middle threshold)
9 -> 2 = +1 (The series has hit the high and middle thresholds)

hit_counts:计算值达到阈值上限或下限然后越过中间阈值的次数。

上限:7

中限:5

下限:3

相关方法将返回3。任何想法,将不胜感激。

2 个答案:

答案 0 :(得分:1)

假设我理解你想要的东西,你可以试试......:/ / p>

class Array
  def hit_counts(upper=7, middle=5, lower=3)
    limit_broken = false
    each_cons(2).count do |a,b|
      limit_broken = true unless (lower..upper).cover? a
      current_range = Range.new(*[a,b].sort)
      if limit_broken && current_range.cover?(middle)
        limit_broken = false
        true
      else
        false
      end
    end
  end
end

答案 1 :(得分:1)

我采取了不同的方法来解决你的问题。

<强>代码

INF = Float::INFINITY

def score(series, limits)
  last =
    case series.first
    when (-INF..limits[:LOWER]) then :LOWER
    when (limits[:UPPER]..INF)  then :UPPER
    else :MIDDLE
    end
  series[1..-1].count do |n|
    if limits[last] <= n
      score = (last == :LOWER && n >= limits[:MIDDLE])
      last =
        case n
        when (-INF..limits[:MIDDLE]-1) then :LOWER
        when (limits[:UPPER]..INF) then :UPPER
        else :MIDDLE
        end
    else
      score = (last == :UPPER && n <= limits[:MIDDLE])
      last =
        case n
        when (-INF..limits[:LOWER]) then :LOWER
        when (limits[:MIDDLE]+1..INF) then :UPPER
        else :MIDDLE
        end
    end
    score
  end
end

<强>实施例

limits = { LOWER: 3, MIDDLE: 5, UPPER: 7 }

series = [1, 6, 2, 4, 1, 9, 2]
p score(series,limits)  #=> 3

series = [1,5,12,8,10,4,13,3,1,4,6,4,6,9,1]
p score(series, limits) #=> 5

@BroiSatse获得了这两个测试序列的相同结果。

<强>解释

我已将规则更改为我认为具有相同评分的更简单的问题:

  • levels = {LOWER: 3, MIDDLE: 5, UPPER: 7}

  • 玩家从三个等级中的一个开始,:LOWER:MIDDLE:UPPER。如果f = series.first,由变量last保留的级别为:

    • :LOWER if f <= limits[:LOWER]
    • :UPPER if f >= limits[:UPPER]
    • :MIDDLE否则为
      `
  • 玩家将在各个级别之间移动(或保持当前级别),从1移动到:LOWER:MIDDLE时,或者当:UPPER时,得分为:UPPER:MIDDLE移至:LOWERi > 0

  • 对于每个f = series[i],请last。播放器位于limits[last] <= f。移动和评分的规则如下:

    • 如果last(移动到非递减值),则玩家移动到(:LOWER变为):
      • f < limits[:MIDDLE] if :UPPER
      • f >= limits[:UPPER] if :MIDDLE
      • :LOWER否则
      • 如果玩家从:MIDDLE移动到:UPPERf < limits[last],则会对得分进行评分。 `
    • 如果last(移动到递减值),则玩家移动到(:LOWER变为):
      • f <= limits[:LOWER] if :UPPER
      • f > limits[:MIDDLE] if :MIDDLE
      • :UPPER否则
      • 如果玩家从:MIDDLE移动到:LOWER或{{1}},则得分。
  • 对序列中的每个后续元素重复该过程。

代码只是以简单的方式实现这些规则。