1#![deny(unsafe_code)]
3pub mod candidates;
4
5use std::cmp::{min, Ordering};
6use std::fmt;
7use candidates::PrimeWheel210 as PrimeWheel;
8use candidates::{is_prime_candidate, miller_rabin};
9
10const MR_TRIAL_DIVISION_CROSSOVER: u128 = 10_000_000;
14
15const MR_DETERMINISTIC_LIMIT: u128 = 3_317_044_064_679_887_385_961_981;
19
20#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
22pub struct IntFactor {
23 pub integer: u128,
24 pub exponent: u32,
25}
26
27impl IntFactor {
28 #[must_use]
29 pub fn to_vec(&self) -> Vec<u128> {
30 vec![self.integer; self.exponent as usize]
31 }
32}
33
34impl fmt::Display for IntFactor {
35 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36 if self.exponent > 1 {
37 write!(f, "{}^{}", self.integer, self.exponent)
38 } else {
39 write!(f, "{}", self.integer)
40 }
41 }
42}
43
44#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
47pub struct PrimeFactors {
48 factors: Vec<IntFactor>
49}
50
51impl PrimeFactors {
52 fn new() -> Self {
53 PrimeFactors { factors: Vec::with_capacity(8) }
54 }
55 fn add(&mut self, integer: u128, exponent: u32) {
56 self.factors.push(IntFactor { integer, exponent })
57 }
58 #[must_use]
61 pub fn value(&self) -> u128 {
62 self.factors.iter().map(|f| f.integer.pow(f.exponent)).product()
63 }
64 #[must_use]
66 pub fn len(&self) -> usize {
67 self.factors.len()
68 }
69 #[must_use]
71 pub fn count_factors(&self) -> u32 {
72 self.factors.iter().map(|f| f.exponent).sum()
73 }
74 #[must_use]
75 pub fn is_empty(&self) -> bool {
76 self.factors.is_empty()
77 }
78 #[must_use]
79 pub fn is_prime(&self) -> bool {
80 self.count_factors() == 1
81 }
82 #[must_use]
84 pub fn factors(&self) -> &[IntFactor] {
85 &self.factors
86 }
87 #[must_use]
89 pub fn to_vec(&self) -> Vec<u128> {
90 self.factors.iter().flat_map(IntFactor::to_vec).collect()
91 }
92 #[must_use]
95 pub fn gcd(&self, other: &PrimeFactors) -> PrimeFactors {
96 let mut pf = PrimeFactors::new();
97 if self.is_empty() || other.is_empty() { return pf; }
98 let mut s_it = self.factors.iter();
99 let mut o_it = other.factors.iter();
100 let mut s = s_it.next().unwrap();
101 let mut o = o_it.next().unwrap();
102 loop {
103 match s.integer.cmp(&o.integer) {
104 Ordering::Equal => {
105 pf.add(s.integer, min(o.exponent, s.exponent));
106 s = match s_it.next() { Some(n) => n, None => break };
107 o = match o_it.next() { Some(n) => n, None => break };
108 }
109 Ordering::Less => {
110 s = match s_it.next() { Some(n) => n, None => break };
111 }
112 Ordering::Greater => {
113 o = match o_it.next() { Some(n) => n, None => break };
114 }
115 }
116 }
117 pf
118 }
119 #[must_use]
122 pub fn has_any_factor(n: u128) -> bool {
123 if n < 4 { return false; }
124 let pw_iter = PrimeWheel::new();
125 for f in pw_iter {
126 if f * f > n {
127 return false;
128 }
129 if n.is_multiple_of(f) {
130 return true;
131 }
132 }
133 false
134 }
135 #[must_use]
137 pub fn factorize(n: u128) -> Self {
138 if n > MR_TRIAL_DIVISION_CROSSOVER {
140 Self::factorize_large(n)
141 } else {
142 Self::factorize_small(n)
144 }
145 }
146 #[inline]
147 fn factorize_large(n: u128) -> Self {
148 let mut pf = PrimeFactors::new();
149 if n < 2 { return pf; }
150 let mut maxsq = n;
151 let mut x = n;
152 if u128_is_prime(n) {
154 pf.add(n, 1);
155 return pf;
156 }
157 let pw_iter = PrimeWheel::new();
158 for f in pw_iter {
159 if f * f > maxsq { break; }
160 let mut c = 0;
161 while x.is_multiple_of(f) {
162 x /= f;
163 c += 1;
164 }
165 if c > 0 {
166 maxsq = x;
167 pf.add(f, c);
168 if x > MR_TRIAL_DIVISION_CROSSOVER && u128_is_prime(x) {
170 pf.add(x, 1);
171 x = 1;
172 break;
173 }
174 }
175 if x == 1 { break; }
176 }
177 if x > 1 {
178 pf.add(x, 1);
179 }
180 pf
181 }
182 #[inline]
183 fn factorize_small(n: u128) -> Self {
184 let mut pf = PrimeFactors::new();
185 if n < 2 { return pf; }
186 let mut maxsq = n;
187 let mut x = n;
188 let pw_iter = PrimeWheel::new();
189 for f in pw_iter {
190 if f * f > maxsq { break; }
191 let mut c = 0;
192 while x.is_multiple_of(f) {
193 x /= f;
194 c += 1;
195 }
196 if c > 0 {
197 maxsq = x;
198 pf.add(f, c);
199 }
200 if x == 1 { break; }
201 }
202 if x > 1 {
203 pf.add(x, 1);
204 }
205 pf
206 }
207}
208
209impl fmt::Display for PrimeFactors {
210 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
211 for (i, factor) in self.factors.iter().enumerate() {
212 if i > 0 {
213 f.write_str(" * ")?;
214 }
215 write!(f, "{factor}")?;
216 }
217 Ok(())
218 }
219}
220
221impl<'a> IntoIterator for &'a PrimeFactors {
223 type Item = &'a IntFactor;
224 type IntoIter = std::slice::Iter<'a, IntFactor>;
225
226 fn into_iter(self) -> Self::IntoIter {
227 self.factors.iter()
228 }
229}
230
231impl IntoIterator for PrimeFactors {
233 type Item = IntFactor;
234 type IntoIter = std::vec::IntoIter<IntFactor>;
235
236 fn into_iter(self) -> Self::IntoIter {
237 self.factors.into_iter()
238 }
239}
240
241#[derive(Clone, Debug)]
245pub struct PrimeNumbers {
246 wheel: PrimeWheel,
247}
248
249impl PrimeNumbers {
250 #[must_use]
251 pub fn new() -> Self {
252 Self { wheel: PrimeWheel::new() }
253 }
254 #[must_use]
256 pub fn from(start: u128) -> Self {
257 Self { wheel: PrimeWheel::from(start) }
258 }
259}
260
261impl Default for PrimeNumbers {
262 fn default() -> Self {
263 Self::new()
264 }
265}
266
267impl Iterator for PrimeNumbers {
268 type Item = u128;
269
270 fn next(&mut self) -> Option<Self::Item> {
271 self.wheel.by_ref().find(|&n| u128_is_prime(n))
272 }
273}
274
275#[derive(Clone, Debug)]
279pub struct DescendingPrimes {
280 wheel: PrimeWheel,
281}
282
283impl DescendingPrimes {
284 #[must_use]
286 pub fn from(start: u128) -> Self {
287 Self { wheel: PrimeWheel::from(start.saturating_add(1)) }
288 }
289}
290
291impl Iterator for DescendingPrimes {
292 type Item = u128;
293
294 fn next(&mut self) -> Option<Self::Item> {
295 loop {
296 let candidate = self.wheel.prev()?;
297 if u128_is_prime(candidate) {
298 return Some(candidate);
299 }
300 }
301 }
302}
303
304#[must_use]
314pub fn u128_is_prime(n: u128) -> bool {
315 if !is_prime_candidate(n) { return false; }
316 const SMALL_PRIMES: &[u128] = &[
321 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
322 ];
323 for &p in SMALL_PRIMES {
324 if n == p { return true; }
325 if n.is_multiple_of(p) { return false; }
326 }
327 if n < MR_DETERMINISTIC_LIMIT {
328 return miller_rabin(n);
329 }
330 if !miller_rabin(n) { return false; }
332 !PrimeFactors::has_any_factor(n)
335}
336
337#[must_use]
341pub fn next_prime(n: u128) -> u128 {
342 PrimeNumbers::from(n).next().unwrap()
343}
344
345#[must_use]
349pub fn prev_prime(n: u128) -> Option<u128> {
350 if n < 2 {
351 return None;
352 }
353 DescendingPrimes::from(n).next()
354}
355
356#[must_use]
363pub fn primefactor_gcd(this: u128, that: u128) -> PrimeFactors {
364 if this == 0 {
365 return PrimeFactors::factorize(that);
366 }
367 if that == 0 {
368 return PrimeFactors::factorize(this);
369 }
370 let pf_this = PrimeFactors::factorize(this);
371 let pf_that = PrimeFactors::factorize(that);
372 pf_this.gcd(&pf_that)
373}
374
375#[must_use]
379pub fn u128_gcd(this: u128, that: u128) -> u128 {
380 let mut a = this;
381 let mut b = that;
382 while b > 0 {
383 let c = b;
384 b = a % b;
385 a = c;
386 }
387 a
388}
389
390#[must_use]
392pub fn u128_lcm(this: u128, that: u128) -> u128 {
393 checked_u128_lcm(this, that).expect("u128_lcm overflow")
394}
395
396#[must_use]
397pub fn checked_u128_lcm(this: u128, that: u128) -> Option<u128> {
398 if this == 0 || that == 0 {
399 return Some(0);
400 }
401 let gcd = u128_gcd(this, that);
402 (this / gcd).checked_mul(that)
403}