isomer 0.0.0

Calculate the number of isomers
Documentation
use crossbeam_skiplist::SkipMap;
use dashu::integer::IBig;
use num_traits::{One, Zero};


pub struct SymmetricGroupCache {
    c000598: SkipMap<usize, IBig>,
    c000642: SkipMap<usize, IBig>,
}

impl Default for SymmetricGroupCache {
    fn default() -> Self {
        let c000598 = SkipMap::new();
        c000598.insert(0, IBig::one());
        Self {
            c000598,
            c000642: Default::default(),
        }
    }
}

/// Cycle index of the symmetric group
fn cycle_index<F>(n: usize, f: &F, k: usize) -> IBig
    where F: Fn(usize) -> IBig
{
    if n == 0 {
        return if k == 0 { IBig::one() } else { IBig::zero() };
    }
    if n == 1 {
        return f(k);
    }
    let mut r = IBig::zero();
    for i in 1..=n {
        let mut sum = IBig::zero();
        for j in (0..=k).step_by(i) {
            sum += f(j / i) * cycle_index(n - i, f, k - j);
        }
        r += sum;
    }
    r / n
}


impl SymmetricGroupCache {
    /// Number of rooted ternary trees with n nodes; number of n-carbon alkyl radicals C(n)H(2n+1) ignoring stereoisomers.
    ///
    /// <https://oeis.org/A000598>
    pub fn a000598(&self, k: usize) -> IBig {
        match self.c000598.get(&k) {
            Some(s) => {
                s.value().clone()
            }
            None => {
                let new = cycle_index(3, &|k| self.a000598(k), k - 1);
                self.c000598.insert(k, new.clone());
                new
            }
        }
    }
    /// Number of isomeric hydrocarbons of the acetylene series with carbon content n.
    ///
    /// <https://oeis.org/A000642>
    pub fn a000642(&self, k: usize) -> IBig {
        match self.c000642.get(&k) {
            Some(s) => {
                s.value().clone()
            }
            None => {
                let new = cycle_index(2, &|k| self.a000598(k), k);
                self.c000642.insert(k, new.clone());
                new
            }
        }
    }
    /// Number of ethylene derivatives with n carbon atoms.
    ///
    /// <https://oeis.org/A000631>
    pub fn a000631(&self, k: usize) -> IBig {
        cycle_index(2, &|k| self.a000642(k), k)
    }
    /// Number of n-node unrooted quartic trees; number of n-carbon alkanes C(n)H(2n+2) ignoring stereoisomers
    ///
    /// <https://oeis.org/A000602>
    pub fn a000602(&self, k: usize) -> IBig {
        self.a000642(k) + if k % 2 == 1 { self.a000642((k - 1) / 2) } else { IBig::zero() } - self.a000631(k - 1)
    }
}