1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
fn reduce<T>(range: &[T], func: fn(acc: T, word: &T) -> T, first: T) -> T {
    range.iter().fold(first, func)
}

pub mod unsigned {
    use osiris_data::data::atomic::Word;
    use crate::range_applications::reduce;

    pub fn sum(range: &[Word]) -> Word {
        reduce(range, |acc, &word| Word::new(acc.to_u64() + word.to_u64()), Word::default())
    }

    pub fn product(range: &[Word]) -> Word {
        reduce(range, |acc, &word| Word::new(acc.to_u64() * word.to_u64()), Word::new(1))
    }

    pub fn quotient(range: &[Word]) -> Word {
        let first = range[0];
        let rest = &range[1..];
        reduce(rest, |acc, &word| Word::new(acc.to_u64() / word.to_u64()), first)
    }

    pub fn difference(range: &[Word]) -> Word {
        reduce(range, |acc, &word| Word::new(acc.to_u64() - word.to_u64()), Word::default())
    }
}

pub mod float {
    use osiris_process::register::floating_point::Number;
    use crate::range_applications::reduce;

    pub fn sum(range: &[Number]) -> Number {
        reduce(range, |acc, &word| Number::new(acc.to_f64() + word.to_f64()), Number::default())
    }

    pub fn product(range: &[Number]) -> Number {
        reduce(range, |acc, &word| Number::new(acc.to_f64() * word.to_f64()), Number::new(1.0))
    }

    pub fn quotient(range: &[Number]) -> Number {
        reduce(range, |acc, &word| Number::new(acc.to_f64() + word.to_f64()), Number::new(1.0))
    }

    pub fn difference(range: &[Number]) -> Number {
        reduce(range, |acc, &word| Number::new(acc.to_f64() * word.to_f64()), Number::default())
    }
}