#* http://rosettacode.org/wiki/Averages/Simple_moving_average
  Simple stateful moving average.
*#

# Object version
SMA = object.new

SMA.init = { period |
  my.period = period
  my.list = []
  my.average = 0
}

SMA.prototype.add = { num |
  true? my.list.length >= my.period
    { my.list.deq }

  my.list << num
  my.average = my.list.reduce(:+) / my.list.length
}

sma3 = SMA.new 3
sma5 = SMA.new 5
[1, 2, 3, 4, 5, 5, 4, 3, 2, 1].each { n |
  p n, " - SMA3: ", sma3.add(n), " SMA5: ", sma5.add(n)
}

# Function version
sma = { period |
  list = []

  { num |
    true? list.length >= period
      { list.deq }

    list << num
    list.reduce(:+) / list.length
  }
}

sma3 = sma 3
sma5 = sma 5
[1, 2, 3, 4, 5, 5, 4, 3, 2, 1].each { n |
  p n, " - SMA3: ", sma3(n), " SMA5: ", sma5(n)
}