pub fn fibonacci(n: u64) -> Option<u64> {
if n == 0 {
return Some(0);
}
let mut a: u64 = 0;
let mut b: u64 = 1;
for _ in 1..n {
let c = a.checked_add(b)?;
a = b;
b = c;
}
Some(b)
}
pub fn fibonacci_sequence(n: usize) -> Vec<u64> {
let mut result = Vec::with_capacity(n.min(94));
for i in 0..n {
match fibonacci(i as u64) {
Some(v) => result.push(v),
None => break,
}
}
result
}
pub fn catalan_number(n: u64) -> Option<u64> {
let mut c: u64 = 1;
for i in 0..n {
let num = c.checked_mul(2 * (2 * i + 1))?;
c = num / (i + 2);
}
Some(c)
}
pub fn bell_number(n: u32) -> Option<u64> {
let n = n as usize;
let mut row = vec![1u64];
for _ in 0..n {
let mut next_row = Vec::with_capacity(row.len() + 1);
next_row.push(*row.last()?);
for j in 0..row.len() {
let val = next_row[j].checked_add(row[j])?;
next_row.push(val);
}
row = next_row;
}
row.first().copied()
}
pub fn stirling_second(n: u32, k: u32) -> Option<u64> {
let n = n as usize;
let k = k as usize;
if k > n {
return Some(0);
}
if k == 0 {
return if n == 0 { Some(1) } else { Some(0) };
}
let mut dp = vec![0u64; k + 1];
dp[0] = 1; for _i in 1..=n {
for j in (1..=k).rev() {
let j_times = (j as u64).checked_mul(dp[j])?;
dp[j] = j_times.checked_add(dp[j - 1])?;
}
dp[0] = 0; }
Some(dp[k])
}
pub fn factorial(n: u64) -> Option<u64> {
let mut result: u64 = 1;
for i in 2..=n {
result = result.checked_mul(i)?;
}
Some(result)
}
pub fn permutation_count(n: u64, k: u64) -> Option<u64> {
if k > n {
return None;
}
let mut result: u64 = 1;
for i in 0..k {
result = result.checked_mul(n - i)?;
}
Some(result)
}
pub fn combination_count(n: u64, k: u64) -> Option<u64> {
if k > n {
return Some(0);
}
let k = k.min(n - k);
let mut result: u64 = 1;
for i in 0..k {
result = result.checked_mul(n - i)?;
result /= i + 1;
}
Some(result)
}
pub fn next_permutation(perm: &mut [usize]) -> bool {
let n = perm.len();
if n < 2 {
return false;
}
let mut i = n - 1;
while i > 0 && perm[i - 1] >= perm[i] {
i -= 1;
}
if i == 0 {
perm.reverse();
return false;
}
let pivot = i - 1;
let mut j = n - 1;
while perm[j] <= perm[pivot] {
j -= 1;
}
perm.swap(pivot, j);
perm[pivot + 1..].reverse();
true
}
pub fn all_permutations(n: usize) -> Vec<Vec<usize>> {
if n == 0 {
return vec![vec![]];
}
let count = factorial(n as u64).unwrap_or(u64::MAX) as usize;
let mut result = Vec::with_capacity(count.min(40320)); let mut perm: Vec<usize> = (0..n).collect();
loop {
result.push(perm.clone());
if !next_permutation(&mut perm) {
break;
}
}
result
}
pub fn all_combinations(n: usize, k: usize) -> Vec<Vec<usize>> {
if k > n {
return Vec::new();
}
if k == 0 {
return vec![vec![]];
}
let count = combination_count(n as u64, k as u64).unwrap_or(0) as usize;
let mut result = Vec::with_capacity(count);
let mut combo: Vec<usize> = (0..k).collect();
loop {
result.push(combo.clone());
let mut i = k;
loop {
if i == 0 {
return result;
}
i -= 1;
if combo[i] < n - k + i {
break;
}
}
combo[i] += 1;
for j in i + 1..k {
combo[j] = combo[j - 1] + 1;
}
}
}
pub fn partition_count(n: usize) -> Option<u64> {
let mut p = vec![0u64; n + 1];
p[0] = 1;
for i in 1..=n {
let mut k: i64 = 1;
loop {
let pent_pos = (k * (3 * k - 1) / 2) as usize;
if pent_pos > i {
break;
}
let sign_pos = k % 2 == 1;
if sign_pos {
p[i] = p[i].checked_add(p[i - pent_pos])?;
} else {
p[i] = p[i].saturating_sub(p[i - pent_pos]);
}
let pent_neg = (k * (3 * k + 1) / 2) as usize;
if pent_neg <= i {
if sign_pos {
p[i] = p[i].checked_add(p[i - pent_neg])?;
} else {
p[i] = p[i].saturating_sub(p[i - pent_neg]);
}
}
k += 1;
}
}
Some(p[n])
}
pub fn enumerate_partitions(n: usize) -> Vec<Vec<usize>> {
if n == 0 {
return vec![vec![]];
}
let mut result = Vec::new();
let mut partition = Vec::with_capacity(n);
enumerate_partitions_helper(n, n, &mut partition, &mut result);
result
}
fn enumerate_partitions_helper(
remaining: usize,
max_part: usize,
current: &mut Vec<usize>,
result: &mut Vec<Vec<usize>>,
) {
if remaining == 0 {
result.push(current.clone());
return;
}
let upper = remaining.min(max_part);
for part in (1..=upper).rev() {
current.push(part);
enumerate_partitions_helper(remaining - part, part, current, result);
current.pop();
}
}
pub fn gcd(mut a: u64, mut b: u64) -> u64 {
while b != 0 {
let t = b;
b = a % b;
a = t;
}
a
}
pub fn lcm(a: u64, b: u64) -> Option<u64> {
if a == 0 || b == 0 {
return Some(0);
}
let g = gcd(a, b);
(a / g).checked_mul(b)
}
pub fn is_prime(n: u64) -> bool {
if n < 2 {
return false;
}
if n == 2 || n == 3 {
return true;
}
if n.is_multiple_of(2) || n.is_multiple_of(3) {
return false;
}
let mut i: u64 = 5;
while i * i <= n {
if n.is_multiple_of(i) || n.is_multiple_of(i + 2) {
return false;
}
i += 6;
}
true
}
pub fn prime_factors(mut n: u64) -> Vec<u64> {
let mut factors = Vec::new();
if n <= 1 {
return factors;
}
while n.is_multiple_of(2) {
factors.push(2);
n /= 2;
}
let mut d: u64 = 3;
while d * d <= n {
while n.is_multiple_of(d) {
factors.push(d);
n /= d;
}
d += 2;
}
if n > 1 {
factors.push(n);
}
factors
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_fibonacci_base_cases() {
assert_eq!(fibonacci(0), Some(0));
assert_eq!(fibonacci(1), Some(1));
assert_eq!(fibonacci(2), Some(1));
}
#[test]
fn test_fibonacci_known_values() {
assert_eq!(fibonacci(10), Some(55));
assert_eq!(fibonacci(20), Some(6765));
assert_eq!(fibonacci(30), Some(832040));
}
#[test]
fn test_fibonacci_max_u64() {
assert_eq!(fibonacci(93), Some(12200160415121876738u64));
assert!(fibonacci(94).is_none());
}
#[test]
fn test_fibonacci_sequence_length() {
let seq = fibonacci_sequence(10);
assert_eq!(seq.len(), 10);
assert_eq!(seq[0], 0);
assert_eq!(seq[1], 1);
assert_eq!(seq[9], 34);
}
#[test]
fn test_fibonacci_sequence_empty() {
assert!(fibonacci_sequence(0).is_empty());
}
#[test]
fn test_catalan_known_values() {
let expected = [1u64, 1, 2, 5, 14, 42, 132, 429, 1430, 4862];
for (i, &exp) in expected.iter().enumerate() {
assert_eq!(catalan_number(i as u64), Some(exp), "C({i}) = {exp}");
}
}
#[test]
fn test_catalan_zero() {
assert_eq!(catalan_number(0), Some(1));
}
#[test]
fn test_bell_known_values() {
let expected = [1u64, 1, 2, 5, 15, 52, 203, 877, 4140, 21147];
for (i, &exp) in expected.iter().enumerate() {
assert_eq!(bell_number(i as u32), Some(exp), "B({i}) = {exp}");
}
}
#[test]
fn test_stirling_second_boundary() {
assert_eq!(stirling_second(0, 0), Some(1));
assert_eq!(stirling_second(1, 0), Some(0));
assert_eq!(stirling_second(1, 1), Some(1));
assert_eq!(stirling_second(2, 5), Some(0)); }
#[test]
fn test_stirling_second_known_values() {
assert_eq!(stirling_second(3, 2), Some(3));
assert_eq!(stirling_second(4, 2), Some(7));
assert_eq!(stirling_second(4, 4), Some(1));
assert_eq!(stirling_second(5, 3), Some(25));
}
#[test]
fn test_factorial_base_cases() {
assert_eq!(factorial(0), Some(1));
assert_eq!(factorial(1), Some(1));
}
#[test]
fn test_factorial_known_values() {
assert_eq!(factorial(5), Some(120));
assert_eq!(factorial(10), Some(3628800));
assert_eq!(factorial(20), Some(2432902008176640000u64));
}
#[test]
fn test_factorial_overflow() {
assert!(factorial(21).is_none());
}
#[test]
fn test_permutation_count() {
assert_eq!(permutation_count(5, 3), Some(60));
assert_eq!(permutation_count(5, 0), Some(1));
assert_eq!(permutation_count(5, 5), Some(120));
}
#[test]
fn test_permutation_count_k_greater_than_n() {
assert_eq!(permutation_count(3, 5), None);
}
#[test]
fn test_combination_count_known() {
assert_eq!(combination_count(5, 2), Some(10));
assert_eq!(combination_count(10, 3), Some(120));
assert_eq!(combination_count(0, 0), Some(1));
}
#[test]
fn test_combination_count_k_greater_than_n() {
assert_eq!(combination_count(3, 5), Some(0));
}
#[test]
fn test_combination_count_symmetry() {
assert_eq!(combination_count(10, 3), combination_count(10, 7));
}
#[test]
fn test_next_permutation_advance() {
let mut p = vec![0usize, 1, 2];
assert!(next_permutation(&mut p));
assert_eq!(p, [0, 2, 1]);
}
#[test]
fn test_next_permutation_last() {
let mut p = vec![2usize, 1, 0];
let advanced = next_permutation(&mut p);
assert!(!advanced);
assert_eq!(p, [0, 1, 2]);
}
#[test]
fn test_next_permutation_single_element() {
let mut p = vec![42usize];
assert!(!next_permutation(&mut p));
}
#[test]
fn test_all_permutations_count() {
assert_eq!(all_permutations(0).len(), 1);
assert_eq!(all_permutations(1).len(), 1);
assert_eq!(all_permutations(3).len(), 6);
assert_eq!(all_permutations(4).len(), 24);
}
#[test]
fn test_all_permutations_content() {
let perms = all_permutations(3);
assert_eq!(perms[0], vec![0, 1, 2]);
assert_eq!(perms[5], vec![2, 1, 0]);
}
#[test]
fn test_all_combinations_count() {
assert_eq!(all_combinations(4, 2).len(), 6);
assert_eq!(all_combinations(5, 3).len(), 10);
assert_eq!(all_combinations(5, 0).len(), 1);
assert_eq!(all_combinations(3, 5).len(), 0);
}
#[test]
fn test_all_combinations_content() {
let combs = all_combinations(4, 2);
assert_eq!(combs[0], vec![0, 1]);
assert_eq!(combs[5], vec![2, 3]);
}
#[test]
fn test_partition_count_known() {
let expected = [1u64, 1, 2, 3, 5, 7, 11, 15, 22, 30, 42];
for (i, &exp) in expected.iter().enumerate() {
assert_eq!(partition_count(i), Some(exp), "p({i}) = {exp}");
}
}
#[test]
fn test_partition_count_larger() {
assert_eq!(partition_count(20), Some(627));
assert_eq!(partition_count(50), Some(204226));
}
#[test]
fn test_enumerate_partitions_zero() {
let parts = enumerate_partitions(0);
assert_eq!(parts, vec![vec![0usize; 0]]);
}
#[test]
fn test_enumerate_partitions_four() {
let parts = enumerate_partitions(4);
assert_eq!(parts.len(), 5);
assert_eq!(parts[0], vec![4]);
assert_eq!(parts[4], vec![1, 1, 1, 1]);
}
#[test]
fn test_enumerate_partitions_sums() {
for n in 0..=8 {
let parts = enumerate_partitions(n);
for p in &parts {
let s: usize = p.iter().sum();
assert_eq!(s, n, "Partition {:?} should sum to {n}", p);
}
}
}
#[test]
fn test_gcd_basic() {
assert_eq!(gcd(48, 18), 6);
assert_eq!(gcd(0, 7), 7);
assert_eq!(gcd(7, 0), 7);
assert_eq!(gcd(0, 0), 0);
assert_eq!(gcd(13, 13), 13);
}
#[test]
fn test_lcm_basic() {
assert_eq!(lcm(4, 6), Some(12));
assert_eq!(lcm(0, 5), Some(0));
assert_eq!(lcm(7, 1), Some(7));
assert_eq!(lcm(21, 6), Some(42));
}
#[test]
fn test_is_prime_small() {
assert!(!is_prime(0));
assert!(!is_prime(1));
assert!(is_prime(2));
assert!(is_prime(3));
assert!(!is_prime(4));
assert!(is_prime(5));
}
#[test]
fn test_is_prime_larger() {
assert!(is_prime(97));
assert!(is_prime(7919));
assert!(!is_prime(100));
assert!(!is_prime(7918));
}
#[test]
fn test_prime_factors_basic() {
assert_eq!(prime_factors(1), Vec::<u64>::new());
assert_eq!(prime_factors(12), vec![2, 2, 3]);
assert_eq!(prime_factors(13), vec![13]);
assert_eq!(prime_factors(360), vec![2, 2, 2, 3, 3, 5]);
}
#[test]
fn test_prime_factors_product_equals_n() {
for n in [2u64, 60, 97, 1024, 999983] {
let factors = prime_factors(n);
let product: u64 = factors.iter().product();
assert_eq!(product, n, "prime_factors({n}) product mismatch");
}
}
#[test]
fn test_prime_factors_zero() {
assert!(prime_factors(0).is_empty());
}
}