brumby 0.7.3

Derivatives and multiples pricing for racing and sports.
pub trait Factorial {
    fn get(&self, n: u8) -> u128;
}

#[derive(Default)]
pub struct Calculator;

impl Factorial for Calculator {
    #[inline]
    fn get(&self, n: u8) -> u128 {
        assert!(n <= 34, "{n}! overflows");
        let mut product = 1u128;
        for i in 2..=n {
            product *= i as u128;
        }
        product
    }
}

const MAX_FACTORIAL_ENTRIES: usize = 35;

pub struct Lookup {
    entries: [u128; MAX_FACTORIAL_ENTRIES]
}
impl Factorial for Lookup {
    #[inline]
    fn get(&self, n: u8) -> u128 {
        self.entries[n as usize]
    }
}

impl Default for Lookup {
    fn default() -> Self {
        let mut entries = [1u128; MAX_FACTORIAL_ENTRIES];
        for i in 2..MAX_FACTORIAL_ENTRIES {
            entries[i] = i as u128 * entries[i - 1];
        }
        Self {
            entries
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    pub fn calculator() {
       test_impl(Calculator);
    }

    #[test]
    pub fn lookup() {
        test_impl(Lookup::default());
    }

    fn test_impl(f: impl Factorial) {
        assert_eq!(1, f.get(0));
        assert_eq!(1, f.get(1));
        assert_eq!(2, f.get(2));
        assert_eq!(6, f.get(3));
        assert_eq!(24, f.get(4));
        assert_eq!(3_628_800, f.get(10));
    }
}