malachite_base/unsigned_vector/arithmetic/canonical_primitive_part.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::num::arithmetic::traits::{
10 CanonicalPrimitivePart, CanonicalPrimitivePartAssign, ContentAndCanonicalPrimitivePart,
11 ContentAndPrimitivePart, PrimitivePart, PrimitivePartAssign,
12};
13use crate::num::basic::unsigneds::PrimitiveUnsigned;
14use crate::unsigned_vector::UnsignedVector;
15
16impl<T: PrimitiveUnsigned> CanonicalPrimitivePart for UnsignedVector<T> {
17 type Output = Self;
18
19 /// Computes the canonical primitive part of an [`UnsignedVector`], taking the vector by value.
20 ///
21 /// The elements of an [`UnsignedVector`] are never negative, so it has only one associate with
22 /// coprime elements, and this is the same as [`primitive_part`](PrimitivePart::primitive_part).
23 ///
24 /// # Worst-case complexity
25 /// $T(n) = O(n)$
26 ///
27 /// $M(n) = O(1)$
28 ///
29 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
30 ///
31 /// # Examples
32 /// ```
33 /// use core::str::FromStr;
34 /// use malachite_base::num::arithmetic::traits::CanonicalPrimitivePart;
35 /// use malachite_base::unsigned_vector::UnsignedVector;
36 ///
37 /// let v = UnsignedVector::<u8>::from_str("(6, 4, 10)").unwrap();
38 /// assert_eq!(v.canonical_primitive_part().to_string(), "(3, 2, 5)");
39 /// ```
40 #[inline]
41 fn canonical_primitive_part(self) -> Self {
42 self.primitive_part()
43 }
44}
45
46impl<T: PrimitiveUnsigned> CanonicalPrimitivePart for &UnsignedVector<T> {
47 type Output = UnsignedVector<T>;
48
49 /// Computes the canonical primitive part of an [`UnsignedVector`], taking the vector by
50 /// reference.
51 ///
52 /// The elements of an [`UnsignedVector`] are never negative, so it has only one associate with
53 /// coprime elements, and this is the same as [`primitive_part`](PrimitivePart::primitive_part).
54 ///
55 /// # Worst-case complexity
56 /// $T(n) = O(n)$
57 ///
58 /// $M(n) = O(n)$
59 ///
60 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
61 ///
62 /// # Examples
63 /// ```
64 /// use core::str::FromStr;
65 /// use malachite_base::num::arithmetic::traits::CanonicalPrimitivePart;
66 /// use malachite_base::unsigned_vector::UnsignedVector;
67 ///
68 /// let v = UnsignedVector::<u8>::from_str("(6, 4, 10)").unwrap();
69 /// assert_eq!((&v).canonical_primitive_part().to_string(), "(3, 2, 5)");
70 /// ```
71 #[inline]
72 fn canonical_primitive_part(self) -> UnsignedVector<T> {
73 self.primitive_part()
74 }
75}
76
77impl<T: PrimitiveUnsigned> CanonicalPrimitivePartAssign for UnsignedVector<T> {
78 /// Replaces an [`UnsignedVector`] with its canonical primitive part.
79 ///
80 /// The elements of an [`UnsignedVector`] are never negative, so it has only one associate with
81 /// coprime elements, and this is the same as [`primitive_part`](PrimitivePart::primitive_part).
82 ///
83 /// # Worst-case complexity
84 /// $T(n) = O(n)$
85 ///
86 /// $M(n) = O(1)$
87 ///
88 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
89 ///
90 /// # Examples
91 /// ```
92 /// use core::str::FromStr;
93 /// use malachite_base::num::arithmetic::traits::CanonicalPrimitivePartAssign;
94 /// use malachite_base::unsigned_vector::UnsignedVector;
95 ///
96 /// let mut v = UnsignedVector::<u8>::from_str("(6, 4, 10)").unwrap();
97 /// v.canonical_primitive_part_assign();
98 /// assert_eq!(v.to_string(), "(3, 2, 5)");
99 /// ```
100 #[inline]
101 fn canonical_primitive_part_assign(&mut self) {
102 self.primitive_part_assign();
103 }
104}
105
106impl<T: PrimitiveUnsigned> ContentAndCanonicalPrimitivePart for UnsignedVector<T> {
107 type Content = T;
108 type CanonicalPrimitivePart = Self;
109
110 /// Computes the content and the canonical primitive part of an [`UnsignedVector`] together,
111 /// taking the vector by value.
112 ///
113 /// The elements of an [`UnsignedVector`] are never negative, so it has only one associate with
114 /// coprime elements, and this is the same as [`primitive_part`](PrimitivePart::primitive_part).
115 ///
116 /// # Worst-case complexity
117 /// $T(n) = O(n)$
118 ///
119 /// $M(n) = O(1)$
120 ///
121 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
122 ///
123 /// # Examples
124 /// ```
125 /// use core::str::FromStr;
126 /// use malachite_base::num::arithmetic::traits::ContentAndCanonicalPrimitivePart;
127 /// use malachite_base::unsigned_vector::UnsignedVector;
128 ///
129 /// let v = UnsignedVector::<u8>::from_str("(6, 4, 10)").unwrap();
130 /// let (content, primitive_part) = v.content_and_canonical_primitive_part();
131 /// assert_eq!(content, 2);
132 /// assert_eq!(primitive_part.to_string(), "(3, 2, 5)");
133 /// ```
134 #[inline]
135 fn content_and_canonical_primitive_part(self) -> (T, Self) {
136 self.content_and_primitive_part()
137 }
138}
139
140impl<T: PrimitiveUnsigned> ContentAndCanonicalPrimitivePart for &UnsignedVector<T> {
141 type Content = T;
142 type CanonicalPrimitivePart = UnsignedVector<T>;
143
144 /// Computes the content and the canonical primitive part of an [`UnsignedVector`] together,
145 /// taking the vector by reference.
146 ///
147 /// The elements of an [`UnsignedVector`] are never negative, so it has only one associate with
148 /// coprime elements, and this is the same as [`primitive_part`](PrimitivePart::primitive_part).
149 ///
150 /// # Worst-case complexity
151 /// $T(n) = O(n)$
152 ///
153 /// $M(n) = O(n)$
154 ///
155 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
156 ///
157 /// # Examples
158 /// ```
159 /// use core::str::FromStr;
160 /// use malachite_base::num::arithmetic::traits::ContentAndCanonicalPrimitivePart;
161 /// use malachite_base::unsigned_vector::UnsignedVector;
162 ///
163 /// let v = UnsignedVector::<u8>::from_str("(6, 4, 10)").unwrap();
164 /// let (content, primitive_part) = (&v).content_and_canonical_primitive_part();
165 /// assert_eq!(content, 2);
166 /// assert_eq!(primitive_part.to_string(), "(3, 2, 5)");
167 /// ```
168 #[inline]
169 fn content_and_canonical_primitive_part(self) -> (T, UnsignedVector<T>) {
170 self.content_and_primitive_part()
171 }
172}