//! 260. Stateful accumulation with scan()
//!
//! `scan()` is like `fold` but emits each intermediate state as an iterator element.
fn main() {
let nums = [1i64, 2, 3, 4, 5];
let running_sum: Vec<i64> = nums.iter()
.scan(0i64, |state, &x| { *state += x; Some(*state) })
.collect();
println!("Running sum: {:?}", running_sum);
let running_product: Vec<i64> = nums.iter()
.scan(1i64, |state, &x| { *state *= x; Some(*state) })
.collect();
println!("Running product: {:?}", running_product);
// Early termination: stop when sum exceeds 6
let partial: Vec<i64> = nums.iter()
.scan(0i64, |state, &x| {
*state += x;
if *state > 6 { None } else { Some(*state) }
})
.collect();
println!("Partial sum (stop >6): {:?}", partial);
let transactions = [100i64, -30, 50, -80, 200];
let balances: Vec<i64> = transactions.iter()
.scan(0i64, |balance, &tx| {
*balance += tx;
Some(*balance)
})
.collect();
println!("Balances: {:?}", balances);
}
#[cfg(test)]
mod tests {
#[test]
fn test_scan_running_sum() {
let result: Vec<i32> = [1, 2, 3, 4, 5].iter()
.scan(0i32, |s, &x| { *s += x; Some(*s) })
.collect();
assert_eq!(result, vec![1, 3, 6, 10, 15]);
}
#[test]
fn test_scan_early_stop() {
let result: Vec<i32> = [1, 2, 3, 4, 5].iter()
.scan(0i32, |s, &x| { *s += x; if *s > 6 { None } else { Some(*s) } })
.collect();
assert_eq!(result, vec![1, 3, 6]);
}
#[test]
fn test_scan_product() {
let result: Vec<i32> = [1, 2, 3, 4].iter()
.scan(1i32, |s, &x| { *s *= x; Some(*s) })
.collect();
assert_eq!(result, vec![1, 2, 6, 24]);
}
}
(* 260. Stateful accumulation with scan() - OCaml *)
let scan init f lst =
let (_, result) = List.fold_left (fun (acc, acc_list) x ->
let new_acc = f acc x in
(new_acc, acc_list @ [new_acc])
) (init, []) lst in
result
let () =
let nums = [1; 2; 3; 4; 5] in
let running_sum = scan 0 (+) nums in
Printf.printf "Running sum: %s\n"
(String.concat ", " (List.map string_of_int running_sum));
let running_product = scan 1 ( * ) nums in
Printf.printf "Running product: %s\n"
(String.concat ", " (List.map string_of_int running_product));
let transactions = [100; -30; 50; -80; 200] in
let balances = scan 0 (+) transactions in
Printf.printf "Balances: %s\n"
(String.concat ", " (List.map string_of_int balances))