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
10#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
12pub struct IntFactor {
13 pub integer: u128,
14 pub exponent: u32,
15}
16
17impl IntFactor {
18 #[must_use]
19 pub fn to_vec(&self) -> Vec<u128> {
20 vec![self.integer; self.exponent as usize]
21 }
22}
23
24impl fmt::Display for IntFactor {
25 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26 if self.exponent > 1 {
27 write!(f, "{}^{}", self.integer, self.exponent)
28 } else {
29 write!(f, "{}", self.integer)
30 }
31 }
32}
33
34#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
37pub struct PrimeFactors {
38 factors: Vec<IntFactor>
39}
40
41impl PrimeFactors {
42 fn new() -> Self {
43 PrimeFactors { factors: Vec::with_capacity(8) }
44 }
45 fn add(&mut self, integer: u128, exponent: u32) {
46 self.factors.push(IntFactor { integer, exponent })
47 }
48 #[must_use]
51 pub fn value(&self) -> u128 {
52 self.factors.iter().map(|f| f.integer.pow(f.exponent)).product()
53 }
54 #[must_use]
56 pub fn len(&self) -> usize {
57 self.factors.len()
58 }
59 #[must_use]
61 pub fn count_factors(&self) -> u32 {
62 self.factors.iter().map(|f| f.exponent).sum()
63 }
64 #[must_use]
65 pub fn is_empty(&self) -> bool {
66 self.factors.is_empty()
67 }
68 #[must_use]
69 pub fn is_prime(&self) -> bool {
70 self.count_factors() == 1
71 }
72 #[must_use]
74 pub fn factors(&self) -> &[IntFactor] {
75 &self.factors
76 }
77 #[must_use]
79 pub fn to_vec(&self) -> Vec<u128> {
80 self.factors.iter().flat_map(IntFactor::to_vec).collect()
81 }
82 #[must_use]
85 pub fn gcd(&self, other: &PrimeFactors) -> PrimeFactors {
86 let mut pf = PrimeFactors::new();
87 if self.is_empty() || other.is_empty() { return pf; }
88 let mut s_it = self.factors.iter();
89 let mut o_it = other.factors.iter();
90 let mut s = s_it.next().unwrap();
91 let mut o = o_it.next().unwrap();
92 loop {
93 match s.integer.cmp(&o.integer) {
94 Ordering::Equal => {
95 pf.add(s.integer, min(o.exponent, s.exponent));
96 s = match s_it.next() { Some(n) => n, None => break };
97 o = match o_it.next() { Some(n) => n, None => break };
98 }
99 Ordering::Less => {
100 s = match s_it.next() { Some(n) => n, None => break };
101 }
102 Ordering::Greater => {
103 o = match o_it.next() { Some(n) => n, None => break };
104 }
105 }
106 }
107 pf
108 }
109 #[must_use]
112 pub fn has_any_factor(n: u128) -> bool {
113 if n < 4 { return false; }
114 let pw_iter = PrimeWheel::new();
115 for f in pw_iter {
116 if f * f > n {
117 return false;
118 }
119 if n.is_multiple_of(f) {
120 return true;
121 }
122 }
123 false
124 }
125 #[must_use]
127 pub fn factorize(n: u128) -> Self {
128 let mut pf = PrimeFactors::new();
129 if n < 2 { return pf; }
130 let mut maxsq = n;
132 let mut x = n;
133 let pw_iter = PrimeWheel::new();
134 for f in pw_iter {
135 if f * f > maxsq {
136 break;
137 }
138 let mut c = 0;
139 while x.is_multiple_of(f) {
140 x /= f;
141 c += 1;
142 }
143 if c > 0 {
144 maxsq = x;
146 pf.add(f, c);
147 }
148 if x == 1 {
149 break;
150 }
151 }
152 if x > 1 || pf.is_empty() {
153 pf.add(x, 1);
155 }
156 pf
157 }
158}
159
160impl fmt::Display for PrimeFactors {
161 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
162 let parts: Vec<_> = self.factors.iter()
163 .map(|f| f.to_string())
164 .collect();
165 write!(f, "{}", parts.join(" * "))
166 }
167}
168
169impl<'a> IntoIterator for &'a PrimeFactors {
171 type Item = &'a IntFactor;
172 type IntoIter = std::slice::Iter<'a, IntFactor>;
173
174 fn into_iter(self) -> Self::IntoIter {
175 self.factors.iter()
176 }
177}
178
179impl IntoIterator for PrimeFactors {
181 type Item = IntFactor;
182 type IntoIter = std::vec::IntoIter<IntFactor>;
183
184 fn into_iter(self) -> Self::IntoIter {
185 self.factors.into_iter()
186 }
187}
188
189#[derive(Clone, Debug)]
193pub struct PrimeNumbers {
194 wheel: PrimeWheel,
195}
196
197impl PrimeNumbers {
198 #[must_use]
199 pub fn new() -> Self {
200 Self { wheel: PrimeWheel::new() }
201 }
202 #[must_use]
204 pub fn from(start: u128) -> Self {
205 Self { wheel: PrimeWheel::from(start) }
206 }
207}
208
209impl Default for PrimeNumbers {
210 fn default() -> Self {
211 Self::new()
212 }
213}
214
215impl Iterator for PrimeNumbers {
216 type Item = u128;
217
218 fn next(&mut self) -> Option<Self::Item> {
219 self.wheel.by_ref().find(|&n| u128_is_prime(n))
220 }
221}
222
223#[must_use]
233pub fn u128_is_prime(n: u128) -> bool {
234 if !is_prime_candidate(n) { return false; }
235 if n < 3_317_044_064_679_887_385_961_981 {
236 return miller_rabin(n);
237 }
238 if !miller_rabin(n) { return false; }
240 !PrimeFactors::has_any_factor(n)
243}
244
245#[must_use]
249pub fn next_prime(n: u128) -> u128 {
250 PrimeNumbers::from(n).next().unwrap()
251}
252
253#[must_use]
260pub fn primefactor_gcd(this: u128, that: u128) -> PrimeFactors {
261 if this == 0 {
262 return PrimeFactors::factorize(that);
263 }
264 if that == 0 {
265 return PrimeFactors::factorize(this);
266 }
267 let pf_this = PrimeFactors::factorize(this);
268 let pf_that = PrimeFactors::factorize(that);
269 pf_this.gcd(&pf_that)
270}
271
272#[must_use]
276pub fn u128_gcd(this: u128, that: u128) -> u128 {
277 let mut a = this;
278 let mut b = that;
279 while b > 0 {
280 let c = b;
281 b = a % b;
282 a = c;
283 }
284 a
285}
286
287#[must_use]
289pub fn u128_lcm(this: u128, that: u128) -> u128 {
290 checked_u128_lcm(this, that).expect("u128_lcm overflow")
291}
292
293#[must_use]
294pub fn checked_u128_lcm(this: u128, that: u128) -> Option<u128> {
295 if this == 0 || that == 0 {
296 return Some(0);
297 }
298 let gcd = u128_gcd(this, that);
299 (this / gcd).checked_mul(that)
300}