1use super::functions::*;
5
6#[allow(dead_code)]
8#[derive(Debug, Clone)]
9pub struct FibonacciUtil;
10#[allow(dead_code)]
11impl FibonacciUtil {
12 pub fn fib(n: u64) -> u64 {
14 if n == 0 {
15 return 0;
16 }
17 if n == 1 {
18 return 1;
19 }
20 let mut a = 0u64;
21 let mut b = 1u64;
22 for _ in 2..=n {
23 let c = a.saturating_add(b);
24 a = b;
25 b = c;
26 }
27 b
28 }
29 pub fn is_fibonacci(n: u64) -> bool {
31 let check = |k: u64| -> bool {
32 let sqrt = (k as f64).sqrt() as u64;
33 sqrt * sqrt == k || (sqrt + 1) * (sqrt + 1) == k
34 };
35 let n5 = 5u64.saturating_mul(n.saturating_mul(n));
36 check(n5.saturating_add(4)) || (n5 >= 4 && check(n5 - 4))
37 }
38 pub fn zeckendorf(mut n: u64) -> Vec<u64> {
41 if n == 0 {
42 return vec![0];
43 }
44 let mut all_fibs = vec![1u64, 1];
45 while *all_fibs
46 .last()
47 .expect("all_fibs is non-empty: initialized with [1, 1]")
48 < n
49 {
50 let len = all_fibs.len();
51 all_fibs.push(all_fibs[len - 1].saturating_add(all_fibs[len - 2]));
52 }
53 all_fibs.retain(|&x| x <= n);
54 all_fibs.dedup();
55 let mut result = Vec::new();
56 for &fib in all_fibs.iter().rev() {
57 if fib <= n {
58 result.push(fib);
59 n -= fib;
60 }
61 }
62 result
63 }
64}
65#[allow(dead_code)]
67#[derive(Debug, Clone)]
68pub struct ArithmeticFunctions;
69#[allow(dead_code)]
70impl ArithmeticFunctions {
71 pub fn euler_totient(n: u64) -> u64 {
73 if n == 0 {
74 return 0;
75 }
76 let mut result = n;
77 let mut temp = n;
78 let mut p = 2u64;
79 while p * p <= temp {
80 if temp % p == 0 {
81 while temp % p == 0 {
82 temp /= p;
83 }
84 result -= result / p;
85 }
86 p += 1;
87 }
88 if temp > 1 {
89 result -= result / temp;
90 }
91 result
92 }
93 pub fn mobius(mut n: u64) -> i32 {
95 if n == 1 {
96 return 1;
97 }
98 let mut num_prime_factors = 0i32;
99 let mut p = 2u64;
100 while p * p <= n {
101 if n % p == 0 {
102 num_prime_factors += 1;
103 n /= p;
104 if n % p == 0 {
105 return 0;
106 }
107 }
108 p += 1;
109 }
110 if n > 1 {
111 num_prime_factors += 1;
112 }
113 if num_prime_factors % 2 == 0 {
114 1
115 } else {
116 -1
117 }
118 }
119 pub fn num_divisors(n: u64) -> u64 {
121 if n == 0 {
122 return 0;
123 }
124 (1..=n).filter(|&d| n % d == 0).count() as u64
125 }
126 pub fn sum_of_divisors(n: u64) -> u64 {
128 if n == 0 {
129 return 0;
130 }
131 (1..=n).filter(|&d| n % d == 0).sum()
132 }
133}
134#[allow(dead_code)]
136#[derive(Debug, Clone)]
137pub struct CollatzUtil;
138#[allow(dead_code)]
139impl CollatzUtil {
140 pub fn sequence(mut n: u64) -> Vec<u64> {
142 let mut seq = vec![n];
143 while n != 1 {
144 n = if n % 2 == 0 { n / 2 } else { 3 * n + 1 };
145 seq.push(n);
146 if seq.len() > 10_000 {
147 break;
148 }
149 }
150 seq
151 }
152 pub fn stopping_time(n: u64) -> Option<usize> {
154 let seq = Self::sequence(n);
155 if *seq
156 .last()
157 .expect("seq is non-empty: sequence(n) always includes n")
158 == 1
159 {
160 Some(seq.len() - 1)
161 } else {
162 None
163 }
164 }
165}