malachite_nz/natural/factorization/primes.rs
1// Copyright © 2025 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::natural::Natural;
10use malachite_base::num::conversion::traits::SaturatingFrom;
11use malachite_base::num::factorization::primes::{PrimesIterator, PrimesLessThanIterator};
12use malachite_base::num::factorization::traits::Primes;
13
14/// An iterator over that generates all prime [`Natural`]s less than a given value.
15///
16/// This `struct` is created by [`Natural::primes_less_than`] and
17/// [`Natural::primes_less_than_or_equal_to`]; see their documentation for more.
18#[derive(Clone, Debug)]
19pub struct NaturalPrimesLessThanIterator(PrimesLessThanIterator<u64>);
20
21impl Iterator for NaturalPrimesLessThanIterator {
22 type Item = Natural;
23
24 #[inline]
25 fn next(&mut self) -> Option<Natural> {
26 self.0.next().map(Natural::from)
27 }
28}
29
30/// An iterator over that generates all prime [`Natural`]s.
31///
32/// This `struct` is created by [`Natural::primes`]; see its documentation for more.
33#[derive(Clone, Debug)]
34pub struct NaturalPrimesIterator(PrimesIterator<u64>);
35
36impl Iterator for NaturalPrimesIterator {
37 type Item = Natural;
38
39 #[inline]
40 fn next(&mut self) -> Option<Natural> {
41 self.0.next().map(Natural::from)
42 }
43}
44
45impl Primes for Natural {
46 type I = NaturalPrimesIterator;
47 type LI = NaturalPrimesLessThanIterator;
48
49 /// Returns an iterator that generates all primes less than a given value.
50 ///
51 /// The iterator produced by `primes_less_than(n)` generates the same primes as the iterator
52 /// produced by `primes().take_while(|&p| p < n)`, but the latter would be slower because it
53 /// doesn't know in advance how large its prime sieve should be, and might have to create larger
54 /// and larger prime sieves.
55 ///
56 /// # Worst-case complexity (amortized)
57 /// $T(i) = O(\log \log i)$
58 ///
59 /// $M(i) = O(1)$
60 ///
61 /// where $T$ is time, $M$ is additional memory, and $i$ is the iteration index.
62 ///
63 /// # Examples
64 /// ```
65 /// use itertools::Itertools;
66 /// use malachite_base::num::factorization::traits::Primes;
67 /// use malachite_base::strings::ToDebugString;
68 /// use malachite_nz::natural::Natural;
69 ///
70 /// assert_eq!(
71 /// Natural::primes_less_than(&Natural::from(10u32))
72 /// .collect_vec()
73 /// .to_debug_string(),
74 /// "[2, 3, 5, 7]"
75 /// );
76 /// assert_eq!(
77 /// Natural::primes_less_than(&Natural::from(11u32))
78 /// .collect_vec()
79 /// .to_debug_string(),
80 /// "[2, 3, 5, 7]"
81 /// );
82 /// assert_eq!(
83 /// Natural::primes_less_than(&Natural::from(100u32))
84 /// .collect_vec()
85 /// .to_debug_string(),
86 /// "[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, \
87 /// 83, 89, 97]"
88 /// );
89 /// ```
90 #[inline]
91 fn primes_less_than(n: &Natural) -> NaturalPrimesLessThanIterator {
92 NaturalPrimesLessThanIterator(u64::primes_less_than(&u64::saturating_from(n)))
93 }
94
95 /// Returns an iterator that generates all primes less than or equal to a given value.
96 ///
97 /// The iterator produced by `primes_less_than_or_equal_to(n)` generates the same primes as the
98 /// iterator produced by `primes().take_while(|&p| p <= n)`, but the latter would be slower
99 /// because it doesn't know in advance how large its prime sieve should be, and might have to
100 /// create larger and larger prime sieves.
101 ///
102 /// # Worst-case complexity (amortized)
103 /// $T(i) = O(\log \log i)$
104 ///
105 /// $M(i) = O(1)$
106 ///
107 /// where $T$ is time, $M$ is additional memory, and $i$ is the iteration index.
108 ///
109 /// # Examples
110 /// ```
111 /// use itertools::Itertools;
112 /// use malachite_base::num::factorization::traits::Primes;
113 /// use malachite_base::strings::ToDebugString;
114 /// use malachite_nz::natural::Natural;
115 ///
116 /// assert_eq!(
117 /// Natural::primes_less_than_or_equal_to(&Natural::from(10u32))
118 /// .collect_vec()
119 /// .to_debug_string(),
120 /// "[2, 3, 5, 7]"
121 /// );
122 /// assert_eq!(
123 /// Natural::primes_less_than_or_equal_to(&Natural::from(11u32))
124 /// .collect_vec()
125 /// .to_debug_string(),
126 /// "[2, 3, 5, 7, 11]"
127 /// );
128 /// assert_eq!(
129 /// Natural::primes_less_than_or_equal_to(&Natural::from(100u32))
130 /// .collect_vec()
131 /// .to_debug_string(),
132 /// "[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, \
133 /// 83, 89, 97]"
134 /// );
135 /// ```
136 #[inline]
137 fn primes_less_than_or_equal_to(n: &Natural) -> NaturalPrimesLessThanIterator {
138 NaturalPrimesLessThanIterator(u64::primes_less_than_or_equal_to(&u64::saturating_from(n)))
139 }
140
141 /// Returns all [`Natural`] primes.
142 ///
143 /// # Worst-case complexity (amortized)
144 /// $T(i) = O(\log \log i)$
145 ///
146 /// $M(i) = O(1)$
147 ///
148 /// where $T$ is time, $M$ is additional memory, and $i$ is the iteration index.
149 ///
150 /// # Examples
151 /// ```
152 /// use itertools::Itertools;
153 /// use malachite_base::num::conversion::traits::ConvertibleFrom;
154 /// use malachite_base::num::factorization::traits::Primes;
155 /// use malachite_base::strings::ToDebugString;
156 /// use malachite_nz::natural::Natural;
157 ///
158 /// assert_eq!(
159 /// Natural::primes()
160 /// .take_while(|p| u8::convertible_from(p))
161 /// .collect_vec()
162 /// .to_debug_string(),
163 /// "[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, \
164 /// 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, \
165 /// 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251]"
166 /// );
167 /// ```
168 #[inline]
169 fn primes() -> NaturalPrimesIterator {
170 NaturalPrimesIterator(u64::primes())
171 }
172}