// Ten days of readings, and three questions answered from the latest day // backwards: recent moving averages, recent day-over-day changes, and every // third day counted back from today. // // nikaia run // moving average over 3 days, latest first: // 25 // … // peak: day 9, 28 // every third day, from today back: 28 22 17 12 // // Shows: sequence pipelines (`windows`, `map`, `zip`, `skip`, `step_by`) walked // from the back with `rev`, and a range used as a value. // // A package: `nikaia run` in this directory runs it, and `nikaia test` checks // what it prints against `tests/` (ADR-269 D13). fn main() { let readings = [12, 14, 13, 17, 19, 18, 22, 25, 24, 28] let n = 3 println(f"moving average over {n} days, latest first:") let averages = readings.windows(n).map(fn(w) { let mut total = 0 for x in w { total += x } total / n }) // `rev` walks the pipeline from its back end; nothing is collected or // copied on the way. `windows` hands out views of the list, and a `map` // walked from the back is its input walked from the back. Not every // sequence has a back end: `io::lines().rev()` is a compile error. for average in averages.rev().take(3) { println(f" {average}") } println("day over day, latest first:") let changes = readings.iter().zip(readings.iter().skip(1)) // `zip` and `skip` can be walked from the back only when the length of // what goes in is known. A list's is; after a `filter` it would not be. for (before, after) in changes.rev().take(3) { println(f" {before} -> {after}: {after - before}") } // A range is a value: `days` is walked twice, here and below. A produced // sequence such as `averages` can be walked only once. let days = 0.. readings[peak] { peak = day } } println(f"peak: day {peak}, {readings[peak]}") print("every third day, from today back:") for day in days.step_by(3).rev() { print(f" {readings[day]}") } println("") }