Skip to main content

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}