classics.rs
4.0 kB · rust · 152 lines
1/// Returns the even numbers up to the limit.2pub fn evens(limit: usize) -> Vec<usize> {3 (0..=limit).step_by(2).collect()4}56/// Returns the odd numbers up to the limit.7pub fn odds(limit: usize) -> Vec<usize> {8 (1..=limit).step_by(2).collect()9}1011/// Returns the powers of two up to the limit.12pub fn binary(limit: usize) -> Vec<usize> {13 let mut out = Vec::new();14 let mut value = 1;15 while value <= limit {16 out.push(value);17 value *= 2;18 }19 out20}2122/// Returns the distinct Fibonacci numbers up to the limit.23pub fn fibonacci(limit: usize) -> Vec<usize> {24 let mut out = Vec::new();25 let (mut a, mut b) = (0usize, 1usize);26 while a <= limit {27 if !out.contains(&a) {28 out.push(a);29 }30 let next = a + b;31 a = b;32 b = next;33 }34 out35}3637/// Returns the distinct Catalan numbers up to the limit.38///39/// ```40/// assert_eq!(mrlynum::classics::catalan(50), vec![1, 2, 5, 14, 42]);41/// ```42pub fn catalan(limit: usize) -> Vec<usize> {43 let mut out = Vec::new();44 let mut value: u128 = 1;45 let mut index: u128 = 0;46 while value <= limit as u128 {47 if out.last() != Some(&(value as usize)) {48 out.push(value as usize);49 }50 value = value * 2 * (2 * index + 1) / (index + 2);51 index += 1;52 }53 out54}5556/// Returns the primes up to the limit by sieve.57///58/// ```59/// assert_eq!(mrlynum::classics::primes(20), vec![2, 3, 5, 7, 11, 13, 17, 19]);60/// ```61pub fn primes(limit: usize) -> Vec<usize> {62 if limit < 2 {63 return Vec::new();64 }65 let mut sieve = vec![true; limit + 1];66 sieve[0] = false;67 sieve[1] = false;68 let mut p = 2;69 while p * p <= limit {70 if sieve[p] {71 let mut m = p * p;72 while m <= limit {73 sieve[m] = false;74 m += p;75 }76 }77 p += 1;78 }79 (2..=limit).filter(|&n| sieve[n]).collect()80}8182/// Returns the factorial of the number, the product of one through it, exact up to thirty-four.83pub fn factorial(number: usize) -> u128 {84 (1..=number as u128).product()85}8687/// Returns the greatest common divisor of two numbers by the Euclidean algorithm.88///89/// ```90/// assert_eq!(mrlynum::classics::gcd(12, 18), 6);91/// assert_eq!(mrlynum::classics::gcd(7, 0), 7);92/// ```93pub fn gcd(a: u128, b: u128) -> u128 {94 let (mut a, mut b) = (a, b);95 while b != 0 {96 (a, b) = (b, a % b);97 }98 a99}100101/// Reduces a fraction to its lowest terms, a zero numerator and denominator reading as zero over one.102///103/// ```104/// assert_eq!(mrlynum::classics::reduce(64, 128), (1, 2));105/// ```106pub fn reduce(numerator: u128, denominator: u128) -> (u128, u128) {107 match gcd(numerator, denominator) {108 0 => (0, 1),109 divisor => (numerator / divisor, denominator / divisor),110 }111}112113#[cfg(test)]114mod tests {115 use super::*;116 #[test]117 fn evens_and_odds() {118 assert_eq!(evens(8), vec![0, 2, 4, 6, 8]);119 assert_eq!(odds(8), vec![1, 3, 5, 7]);120 }121 #[test]122 fn binary_powers() {123 assert_eq!(binary(20), vec![1, 2, 4, 8, 16]);124 assert_eq!(binary(0), Vec::<usize>::new());125 }126 #[test]127 fn fibonacci_dedups_zero_one() {128 assert_eq!(fibonacci(13), vec![0, 1, 2, 3, 5, 8, 13]);129 }130 #[test]131 fn primes_to_twenty() {132 assert_eq!(primes(20), vec![2, 3, 5, 7, 11, 13, 17, 19]);133 assert_eq!(primes(1), Vec::<usize>::new());134 }135 #[test]136 fn catalan_dedups_the_double_one() {137 assert_eq!(catalan(1500), vec![1, 2, 5, 14, 42, 132, 429, 1430]);138 assert_eq!(catalan(0), Vec::<usize>::new());139 }140 #[test]141 fn catalan_matches_the_binomial_form() {142 let list = catalan(40_000_000);143 for (n, &value) in list.iter().enumerate().skip(1) {144 let m = n + 1;145 let mut binom: u128 = 1;146 for i in 0..m {147 binom = binom * (2 * m - i) as u128 / (i + 1) as u128;148 }149 assert_eq!(value as u128, binom / (m as u128 + 1), "{m}");150 }151 }152}