peuler 0.1.0

A Rust crate with solutions to the Project Euler problems
Documentation
use crate::Solution;
use malachite::Natural;
use malachite::base::num::basic::traits::One;
use std::sync::LazyLock;

problem!(Problem0053, 53, "Combinatoric Selections");

impl Solution for Problem0053 {
    fn solve(&self) -> String {
        let mut result = 0;
        let limit = Natural::from(LIMIT);

        for n in LOW_N..(N + 1) {
            let limit_r = (n >> 1) + 1;
            for r in 0..limit_r {
                let value = &FACT_CACHE[n] / (&FACT_CACHE[r] * &FACT_CACHE[n - r]);
                if value > limit {
                    result += (limit_r - r) << 1;
                    if n % 2 == 0 {
                        result -= 1;
                    }
                    break;
                }
            }
        }

        result.to_string()
    }
}

const LOW_N: usize = 23;
const N: usize = 100;
const LIMIT: usize = 1_000_000;

static FACT_CACHE: LazyLock<[Natural; N + 1]> = LazyLock::new(|| {
    let mut cache = [Natural::ONE; N + 1];
    let mut current_num = Natural::ONE;

    for (i, position) in cache.iter_mut().enumerate().skip(2) {
        current_num *= Natural::from(i);
        *position = current_num.clone();
    }

    cache
});