malachite_nz/natural/arithmetic/coprime_with.rs
1// Copyright © 2026 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;
10#[cfg(feature = "test_build")]
11use malachite_base::num::arithmetic::traits::DivisibleBy;
12use malachite_base::num::arithmetic::traits::{CoprimeWith, Gcd, Parity};
13
14pub_test! {coprime_with_check_2(x: Natural, y: Natural) -> bool {
15 (x.odd() || y.odd()) && x.gcd(y) == 1u32
16}}
17
18#[cfg(feature = "test_build")]
19pub fn coprime_with_check_2_3(x: Natural, y: Natural) -> bool {
20 (x.odd() || y.odd())
21 && (!(&x).divisible_by(Natural::from(3u32)) || !(&y).divisible_by(Natural::from(3u32)))
22 && x.gcd(y) == 1u32
23}
24
25#[cfg(feature = "test_build")]
26pub fn coprime_with_check_2_3_5(x: Natural, y: Natural) -> bool {
27 if x.even() && y.even() {
28 false
29 } else {
30 let x15 = &x % Natural::from(15u32);
31 let y15 = &y % Natural::from(15u32);
32 if (x15 == 0u32 || x15 == 3u32 || x15 == 6u32 || x15 == 9u32 || x15 == 12u32)
33 && (y15 == 0u32 || y15 == 3u32 || y15 == 6u32 || y15 == 9u32 || y15 == 12u32)
34 {
35 return false;
36 }
37 if (x15 == 0u32 || x15 == 5u32 || x15 == 10u32)
38 && (y15 == 0u32 || y15 == 5u32 || y15 == 10u32)
39 {
40 return false;
41 }
42 x.gcd(y) == 1u32
43 }
44}
45
46pub_test! {coprime_with_check_2_val_ref(x: Natural, y: &Natural) -> bool {
47 (x.odd() || y.odd()) && x.gcd(y) == 1u32
48}}
49
50pub_test! {coprime_with_check_2_ref_val(x: &Natural, y: Natural) -> bool {
51 (x.odd() || y.odd()) && x.gcd(y) == 1u32
52}}
53
54pub_test! {coprime_with_check_2_ref_ref(x: &Natural, y: &Natural) -> bool {
55 (x.odd() || y.odd()) && x.gcd(y) == 1u32
56}}
57
58impl CoprimeWith<Self> for Natural {
59 /// Returns whether two [`Natural`]s are coprime; that is, whether they have no common factor
60 /// other than 1. Both [`Natural`]s are taken by value.
61 ///
62 /// Every [`Natural`] is coprime with 1. No [`Natural`] is coprime with 0, except 1.
63 ///
64 /// $f(x, y) = (\gcd(x, y) = 1)$.
65 ///
66 /// $f(x, y) = ((k,m,n \in \N \land x=km \land y=kn) \implies k=1)$.
67 ///
68 /// # Worst-case complexity
69 /// $T(n) = O(n (\log n)^2 \log\log n)$
70 ///
71 /// $M(n) = O(n \log n)$
72 ///
73 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
74 /// other.significant_bits())`.
75 ///
76 /// # Examples
77 /// ```
78 /// use malachite_base::num::arithmetic::traits::CoprimeWith;
79 /// use malachite_nz::natural::Natural;
80 ///
81 /// assert_eq!(Natural::from(3u32).coprime_with(Natural::from(5u32)), true);
82 /// assert_eq!(
83 /// Natural::from(12u32).coprime_with(Natural::from(90u32)),
84 /// false
85 /// );
86 /// ```
87 #[inline]
88 fn coprime_with(self, other: Self) -> bool {
89 coprime_with_check_2(self, other)
90 }
91}
92
93impl<'a> CoprimeWith<&'a Self> for Natural {
94 /// Returns whether two [`Natural`]s are coprime; that is, whether they have no common factor
95 /// other than 1. The first [`Natural`] is taken by value and the second by reference.
96 ///
97 /// Every [`Natural`] is coprime with 1. No [`Natural`] is coprime with 0, except 1.
98 ///
99 /// $f(x, y) = (\gcd(x, y) = 1)$.
100 ///
101 /// $f(x, y) = ((k,m,n \in \N \land x=km \land y=kn) \implies k=1)$.
102 ///
103 /// # Worst-case complexity
104 /// $T(n) = O(n (\log n)^2 \log\log n)$
105 ///
106 /// $M(n) = O(n \log n)$
107 ///
108 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
109 /// other.significant_bits())`.
110 ///
111 /// # Examples
112 /// ```
113 /// use malachite_base::num::arithmetic::traits::CoprimeWith;
114 /// use malachite_nz::natural::Natural;
115 ///
116 /// assert_eq!(Natural::from(3u32).coprime_with(&Natural::from(5u32)), true);
117 /// assert_eq!(
118 /// Natural::from(12u32).coprime_with(&Natural::from(90u32)),
119 /// false
120 /// );
121 /// ```
122 #[inline]
123 fn coprime_with(self, other: &'a Self) -> bool {
124 coprime_with_check_2_val_ref(self, other)
125 }
126}
127
128impl CoprimeWith<Natural> for &Natural {
129 /// Returns whether two [`Natural`]s are coprime; that is, whether they have no common factor
130 /// other than 1. The first [`Natural`] is taken by reference and the second by value.
131 ///
132 /// Every [`Natural`] is coprime with 1. No [`Natural`] is coprime with 0, except 1.
133 ///
134 /// $f(x, y) = (\gcd(x, y) = 1)$.
135 ///
136 /// $f(x, y) = ((k,m,n \in \N \land x=km \land y=kn) \implies k=1)$.
137 ///
138 /// # Worst-case complexity
139 /// $T(n) = O(n (\log n)^2 \log\log n)$
140 ///
141 /// $M(n) = O(n \log n)$
142 ///
143 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
144 /// other.significant_bits())`.
145 ///
146 /// # Examples
147 /// ```
148 /// use malachite_base::num::arithmetic::traits::CoprimeWith;
149 /// use malachite_nz::natural::Natural;
150 ///
151 /// assert_eq!(
152 /// (&Natural::from(3u32)).coprime_with(Natural::from(5u32)),
153 /// true
154 /// );
155 /// assert_eq!(
156 /// (&Natural::from(12u32)).coprime_with(Natural::from(90u32)),
157 /// false
158 /// );
159 /// ```
160 #[inline]
161 fn coprime_with(self, other: Natural) -> bool {
162 coprime_with_check_2_ref_val(self, other)
163 }
164}
165
166impl CoprimeWith<&Natural> for &Natural {
167 /// Returns whether two [`Natural`]s are coprime; that is, whether they have no common factor
168 /// other than 1. Both [`Natural`]s are taken by reference.
169 ///
170 /// Every [`Natural`] is coprime with 1. No [`Natural`] is coprime with 0, except 1.
171 ///
172 /// $f(x, y) = (\gcd(x, y) = 1)$.
173 ///
174 /// $f(x, y) = ((k,m,n \in \N \land x=km \land y=kn) \implies k=1)$.
175 ///
176 /// # Worst-case complexity
177 /// $T(n) = O(n (\log n)^2 \log\log n)$
178 ///
179 /// $M(n) = O(n \log n)$
180 ///
181 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
182 /// other.significant_bits())`.
183 ///
184 /// # Examples
185 /// ```
186 /// use malachite_base::num::arithmetic::traits::CoprimeWith;
187 /// use malachite_nz::natural::Natural;
188 ///
189 /// assert_eq!(
190 /// (&Natural::from(3u32)).coprime_with(Natural::from(5u32)),
191 /// true
192 /// );
193 /// assert_eq!(
194 /// (&Natural::from(12u32)).coprime_with(Natural::from(90u32)),
195 /// false
196 /// );
197 /// ```
198 fn coprime_with(self, other: &Natural) -> bool {
199 coprime_with_check_2_ref_ref(self, other)
200 }
201}