dsalgo 0.3.10

A package for Datastructures and Algorithms.
Documentation
use std::ops::*;

use crate::inverse_factorial_table_from_i32::inverse_factorial;

pub fn n_choose<T>(
    n: usize,
    size: usize,
) -> Vec<T>
where
    T: Mul<Output = T> + Div<Output = T> + From<i32> + Clone,
{
    assert!(size > 0);

    let mut f: Vec<T> = vec![0.into(); size];

    f[0] = 1.into();

    for i in 1..size {
        f[i] = f[i - 1].clone() * ((n + 1 - i) as i32).into();
    }

    for (f, inv) in f.iter_mut().zip(inverse_factorial::<T>(size).into_iter()) {
        *f = f.clone() * inv;
    }

    f
}

#[cfg(test)]

mod tests {

    use super::*;

    #[test]

    fn test() {
        use crate::{
            define_const_modulus_macro::Mod1_000_000_007I64,
            modular_int_with_static_modulus::Modint,
        };

        type Mint = Modint<Mod1_000_000_007I64>;

        let res = n_choose::<Mint>(1_000_000_000, 20)
            .into_iter()
            .map(|x| x.0)
            .collect::<Vec<i64>>();

        assert_eq!(
            res,
            [
                1, 1000000000, 28, 999999923, 210, 999999545, 924, 999998291,
                3003, 999995002, 8008, 999987631, 18564, 999972875, 38760,
                999945743, 74613, 999899060, 134596, 999822907
            ]
        );
    }
}