malachite_base/vecs/mod.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
9#[cfg(feature = "random")]
10use crate::num::conversion::traits::ExactFrom;
11#[cfg(feature = "random")]
12use crate::num::random::{RandomUnsignedsLessThan, random_unsigneds_less_than};
13#[cfg(feature = "random")]
14use crate::random::Seed;
15use crate::slices::advance_indices;
16use alloc::string::String;
17use alloc::vec::Vec;
18use core::str::FromStr;
19#[cfg(feature = "random")]
20use rand::prelude::SliceRandom;
21#[cfg(feature = "random")]
22use rand_chacha::ChaCha20Rng;
23
24/// Inserts several copies of a value at the left (beginning) of a [`Vec`].
25///
26/// Using this function is more efficient than inserting the values one by one.
27///
28/// # Worst-case complexity
29/// $T(n, m) = O(n + m)$
30///
31/// $M(n, m) = O(n + m)$
32///
33/// where $T$ is time, $M$ is additional memory, $n$ is `xs.len()` before the function is called,
34/// and $m$ is `pad_size`.
35///
36/// # Examples
37/// ```
38/// use malachite_base::vecs::vec_pad_left;
39///
40/// let mut xs = vec![1, 2, 3];
41/// vec_pad_left::<u32>(&mut xs, 5, 10);
42/// assert_eq!(xs, [10, 10, 10, 10, 10, 1, 2, 3]);
43/// ```
44pub fn vec_pad_left<T: Clone>(xs: &mut Vec<T>, pad_size: usize, pad_value: T) {
45 let old_len = xs.len();
46 xs.resize(old_len + pad_size, pad_value);
47 for i in (0..old_len).rev() {
48 xs.swap(i, i + pad_size);
49 }
50}
51
52/// Deletes several values from the left (beginning) of a [`Vec`].
53///
54/// Using this function is more efficient than deleting the values one by one.
55///
56/// # Worst-case complexity
57/// $T(n, m) = O(\max(1, n - m))$
58///
59/// $M(n, m) = O(1)$
60///
61/// where $T$ is time, $M$ is additional memory, $n$ is `xs.len()` before the function is called,
62/// and $m$ is `delete_size`.
63///
64/// # Panics
65/// Panics if `delete_size` is greater than `xs.len()`.
66///
67/// # Examples
68/// ```
69/// use malachite_base::vecs::vec_delete_left;
70///
71/// let mut xs = vec![1, 2, 3, 4, 5];
72/// vec_delete_left::<u32>(&mut xs, 3);
73/// assert_eq!(xs, [4, 5]);
74/// ```
75pub fn vec_delete_left<T: Copy>(xs: &mut Vec<T>, delete_size: usize) {
76 let old_len = xs.len();
77 xs.copy_within(delete_size..old_len, 0);
78 xs.truncate(old_len - delete_size);
79}
80
81/// Converts a string to an `Vec<T>`, where `T` implements [`FromStr`].
82///
83/// If the string does not represent a valid `Vec<T>`, `None` is returned.
84///
85/// If `T` does not implement [`FromStr`], try using [`vec_from_str_custom`] instead.
86///
87/// Substrings representing `T`s may contain commas. Sometimes this may lead to ambiguities: for
88/// example, the two `Vec<&str>`s `vec!["a, b"]` and `vec!["a", "b"]` both have the string
89/// representation `"[a, b]"`. The parser is greedy, so it will interpet this string as `vec!["a",
90/// "b"]`.
91///
92/// # Examples
93/// ```
94/// use malachite_base::nevers::Never;
95/// use malachite_base::vecs::vec_from_str;
96///
97/// assert_eq!(vec_from_str::<Never>("[]"), Some(vec![]));
98/// assert_eq!(vec_from_str("[5, 6, 7]"), Some(vec![5, 6, 7]));
99/// assert_eq!(
100/// vec_from_str("[false, false, true]"),
101/// Some(vec![false, false, true])
102/// );
103/// assert_eq!(vec_from_str::<bool>("[false, false, true"), None);
104/// ```
105#[inline]
106pub fn vec_from_str<T: FromStr>(src: &str) -> Option<Vec<T>> {
107 vec_from_str_custom(&(|t| t.parse().ok()), src)
108}
109
110/// Converts a string to an `Vec<T>`, given a function to parse a string into a `T`.
111///
112/// If the string does not represent a valid `Option<T>`, `None` is returned.
113///
114/// If `f` just uses [`FromStr::from_str`], you can use [`vec_from_str`] instead.
115///
116/// Substrings representing `T`s may contain commas. Sometimes this may lead to ambiguities: for
117/// example, the two `Vec<&str>`s `vec!["a, b"]` and `vec!["a", "b"]` both have the string
118/// representation `"[a, b]"`. The parser is greedy, so it will interpet this string as `vec!["a",
119/// "b"]`.
120///
121/// # Examples
122/// ```
123/// use malachite_base::options::option_from_str;
124/// use malachite_base::orderings::ordering_from_str;
125/// use malachite_base::vecs::{vec_from_str, vec_from_str_custom};
126/// use std::cmp::Ordering::*;
127///
128/// assert_eq!(
129/// vec_from_str_custom(&ordering_from_str, "[Less, Greater]"),
130/// Some(vec![Less, Greater]),
131/// );
132/// assert_eq!(
133/// vec_from_str_custom(&option_from_str, "[Some(false), None]"),
134/// Some(vec![Some(false), None]),
135/// );
136/// assert_eq!(
137/// vec_from_str_custom(&vec_from_str, "[[], [3], [2, 5]]"),
138/// Some(vec![vec![], vec![3], vec![2, 5]]),
139/// );
140/// assert_eq!(
141/// vec_from_str_custom(&option_from_str::<bool>, "[Some(fals), None]"),
142/// None
143/// );
144/// ```
145pub fn vec_from_str_custom<T>(f: &dyn Fn(&str) -> Option<T>, src: &str) -> Option<Vec<T>> {
146 if !src.starts_with('[') || !src.ends_with(']') {
147 return None;
148 }
149 let mut xs = Vec::new();
150 let mut buffer = String::new();
151 for token in src[1..src.len() - 1].split(", ") {
152 if !buffer.is_empty() {
153 buffer.push_str(", ");
154 }
155 buffer.push_str(token);
156 if let Some(x) = f(&buffer) {
157 xs.push(x);
158 buffer.clear();
159 }
160 }
161 if buffer.is_empty() { Some(xs) } else { None }
162}
163
164#[cfg(feature = "random")]
165/// Uniformly generates a random value from a nonempty [`Vec`].
166///
167/// This `struct` is created by [`random_values_from_vec`]; see its documentation for more.
168#[derive(Clone, Debug)]
169pub struct RandomValuesFromVec<T: Clone> {
170 xs: Vec<T>,
171 indices: RandomUnsignedsLessThan<u64>,
172}
173
174#[cfg(feature = "random")]
175impl<T: Clone> Iterator for RandomValuesFromVec<T> {
176 type Item = T;
177
178 #[inline]
179 fn next(&mut self) -> Option<T> {
180 Some(self.xs[usize::exact_from(self.indices.next().unwrap())].clone())
181 }
182}
183
184#[cfg(feature = "random")]
185/// Uniformly generates a random value from a nonempty [`Vec`].
186///
187/// The iterator owns the data. It may be more convenient for the iterator to return references to a
188/// pre-existing slice, in which case you may use
189/// [`random_values_from_slice`](crate::slices::random_values_from_slice) instead.
190///
191/// The output length is infinite.
192///
193/// $P(x) = 1/n$, where $n$ is `xs.len()`.
194///
195/// # Panics
196/// Panics if `xs` is empty.
197///
198/// # Examples
199/// ```
200/// use itertools::Itertools;
201/// use malachite_base::random::EXAMPLE_SEED;
202/// use malachite_base::vecs::random_values_from_vec;
203///
204/// let xs = vec![2, 3, 5, 7, 11];
205/// assert_eq!(
206/// random_values_from_vec(EXAMPLE_SEED, xs)
207/// .take(10)
208/// .collect_vec(),
209/// &[3, 7, 3, 5, 11, 3, 5, 11, 2, 2]
210/// );
211/// ```
212#[inline]
213pub fn random_values_from_vec<T: Clone>(seed: Seed, xs: Vec<T>) -> RandomValuesFromVec<T> {
214 assert!(!xs.is_empty(), "empty Vec");
215 let indices = random_unsigneds_less_than(seed, u64::exact_from(xs.len()));
216 RandomValuesFromVec { xs, indices }
217}
218
219/// Generates every permutation of a [`Vec`].
220///
221/// This `struct` is created by [`exhaustive_vec_permutations`]; see its documentation for more.
222#[derive(Clone, Debug, Eq, Hash, PartialEq)]
223pub struct ExhaustiveVecPermutations<T: Clone> {
224 xs: Vec<T>,
225 indices: Vec<usize>,
226 done: bool,
227}
228
229impl<T: Clone> Iterator for ExhaustiveVecPermutations<T> {
230 type Item = Vec<T>;
231
232 fn next(&mut self) -> Option<Vec<T>> {
233 if self.done {
234 None
235 } else {
236 let out = Some(self.indices.iter().map(|&i| self.xs[i].clone()).collect());
237 self.done = advance_indices(&mut self.indices);
238 out
239 }
240 }
241}
242
243/// Generates every permutation of a [`Vec`].
244///
245/// The permutations are [`Vec`]s of cloned items. It may be more convenient for the iterator to
246/// return references to a slice, in which case you may use
247/// [`exhaustive_slice_permutations`](crate::slices::exhaustive_slice_permutations) instead.
248///
249/// The permutations are generated in lexicographic order with respect to the ordering in the
250/// [`Vec`].
251///
252/// The output length is $n!$, where $n$ is `xs.len()`.
253///
254/// # Worst-case complexity per iteration
255/// $T(i) = O(\ell)$
256///
257/// $M(i) = O(\ell)$
258///
259/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, and $\ell$ is
260/// `xs.len()`.
261///
262/// # Examples
263/// ```
264/// use itertools::Itertools;
265/// use malachite_base::vecs::exhaustive_vec_permutations;
266///
267/// let css: Vec<String> = exhaustive_vec_permutations(vec!['a', 'b', 'c', 'd'])
268/// .map(|ds| ds.into_iter().collect())
269/// .collect();
270/// assert_eq!(
271/// css.iter().map(String::as_str).collect_vec().as_slice(),
272/// [
273/// "abcd", "abdc", "acbd", "acdb", "adbc", "adcb", "bacd", "badc", "bcad", "bcda", "bdac",
274/// "bdca", "cabd", "cadb", "cbad", "cbda", "cdab", "cdba", "dabc", "dacb", "dbac", "dbca",
275/// "dcab", "dcba"
276/// ]
277/// );
278/// ```
279pub fn exhaustive_vec_permutations<T: Clone>(xs: Vec<T>) -> ExhaustiveVecPermutations<T> {
280 let len = xs.len();
281 ExhaustiveVecPermutations {
282 xs,
283 indices: (0..len).collect(),
284 done: false,
285 }
286}
287
288#[cfg(feature = "random")]
289/// Uniformly generates a random [`Vec`] of values cloned from an original [`Vec`].
290///
291/// This `struct` is created by [`random_vec_permutations`]; see its documentation for more.
292#[derive(Clone, Debug)]
293pub struct RandomVecPermutations<T: Clone> {
294 xs: Vec<T>,
295 indices: Vec<usize>,
296 rng: ChaCha20Rng,
297}
298
299#[cfg(feature = "random")]
300impl<T: Clone> Iterator for RandomVecPermutations<T> {
301 type Item = Vec<T>;
302
303 fn next(&mut self) -> Option<Vec<T>> {
304 self.indices.shuffle(&mut self.rng);
305 Some(self.indices.iter().map(|&i| self.xs[i].clone()).collect())
306 }
307}
308
309#[cfg(feature = "random")]
310/// Uniformly generates a random [`Vec`] of values cloned from an original [`Vec`].
311///
312/// The permutations are [`Vec`]s of cloned items. It may be more convenient for the iterator to
313/// return references to a slice, in which case you may use
314/// [`random_slice_permutations`](crate::slices::random_slice_permutations) instead.
315///
316/// The output length is infinite.
317///
318/// $P(p) = 1/n!$, where $n$ is `xs.len()`.
319///
320/// # Worst-case complexity per iteration
321/// $T(i) = O(\ell)$
322///
323/// $M(i) = O(\ell)$
324///
325/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, and $\ell$ is
326/// `xs.len()`.
327///
328/// # Examples
329/// ```
330/// use itertools::Itertools;
331/// use malachite_base::random::EXAMPLE_SEED;
332/// use malachite_base::vecs::random_vec_permutations;
333///
334/// let css: Vec<String> = random_vec_permutations(EXAMPLE_SEED, vec!['a', 'b', 'c', 'd'])
335/// .take(20)
336/// .map(|ds| ds.into_iter().collect())
337/// .collect();
338/// assert_eq!(
339/// css.iter().map(String::as_str).collect_vec().as_slice(),
340/// [
341/// "dacb", "cbad", "cdab", "cbad", "cdab", "bcda", "bcda", "acbd", "bcda", "dbca", "bdac",
342/// "dbac", "dbca", "bcad", "cadb", "dacb", "acbd", "dbac", "bdca", "abdc"
343/// ]
344/// );
345/// ```
346pub fn random_vec_permutations<T: Clone>(seed: Seed, xs: Vec<T>) -> RandomVecPermutations<T> {
347 let len = xs.len();
348 RandomVecPermutations {
349 xs,
350 indices: (0..len).collect(),
351 rng: seed.get_rng(),
352 }
353}
354
355/// Iterators that generate [`Vec`]s without repetition.
356///
357/// # lex_vecs_length_2
358/// ```
359/// use itertools::Itertools;
360/// use malachite_base::vecs::exhaustive::lex_vecs_length_2;
361///
362/// let xss = lex_vecs_length_2(
363/// ['a', 'b', 'c'].iter().cloned(),
364/// ['x', 'y', 'z'].iter().cloned(),
365/// )
366/// .collect_vec();
367/// assert_eq!(
368/// xss.iter().map(Vec::as_slice).collect_vec().as_slice(),
369/// &[
370/// &['a', 'x'],
371/// &['a', 'y'],
372/// &['a', 'z'],
373/// &['b', 'x'],
374/// &['b', 'y'],
375/// &['b', 'z'],
376/// &['c', 'x'],
377/// &['c', 'y'],
378/// &['c', 'z']
379/// ]
380/// );
381/// ```
382///
383/// # lex_vecs_fixed_length_2_inputs
384/// ```
385/// use itertools::Itertools;
386/// use malachite_base::chars::exhaustive::exhaustive_ascii_chars;
387/// use malachite_base::vecs::exhaustive::lex_vecs_fixed_length_2_inputs;
388///
389/// // We are generating length-3 `Vec`s of `char`s using two input iterators. The first iterator
390/// // (with index 0) produces all ASCII `char`s, and the second (index 1) produces the three
391/// // `char`s `'x'`, `'y'`, and `'z'`. The elements of `output_types` are 0, 1, and 0, meaning that
392/// // the first element of the output `Vec`s will be taken from iterator 0, the second element from
393/// // iterator 1, and the third also from iterator 0.
394/// let xss = lex_vecs_fixed_length_2_inputs(
395/// exhaustive_ascii_chars(),
396/// ['x', 'y', 'z'].iter().cloned(),
397/// &[0, 1, 0],
398/// );
399/// let xss_prefix = xss.take(20).collect_vec();
400/// assert_eq!(
401/// xss_prefix
402/// .iter()
403/// .map(Vec::as_slice)
404/// .collect_vec()
405/// .as_slice(),
406/// &[
407/// &['a', 'x', 'a'],
408/// &['a', 'x', 'b'],
409/// &['a', 'x', 'c'],
410/// &['a', 'x', 'd'],
411/// &['a', 'x', 'e'],
412/// &['a', 'x', 'f'],
413/// &['a', 'x', 'g'],
414/// &['a', 'x', 'h'],
415/// &['a', 'x', 'i'],
416/// &['a', 'x', 'j'],
417/// &['a', 'x', 'k'],
418/// &['a', 'x', 'l'],
419/// &['a', 'x', 'm'],
420/// &['a', 'x', 'n'],
421/// &['a', 'x', 'o'],
422/// &['a', 'x', 'p'],
423/// &['a', 'x', 'q'],
424/// &['a', 'x', 'r'],
425/// &['a', 'x', 's'],
426/// &['a', 'x', 't']
427/// ]
428/// );
429/// ```
430///
431/// # exhaustive_vecs_length_2
432/// ```
433/// use itertools::Itertools;
434/// use malachite_base::vecs::exhaustive::exhaustive_vecs_length_2;
435///
436/// let xss = exhaustive_vecs_length_2(
437/// ['a', 'b', 'c'].iter().cloned(),
438/// ['x', 'y', 'z'].iter().cloned(),
439/// )
440/// .collect_vec();
441/// assert_eq!(
442/// xss.iter().map(Vec::as_slice).collect_vec().as_slice(),
443/// &[
444/// &['a', 'x'],
445/// &['a', 'y'],
446/// &['b', 'x'],
447/// &['b', 'y'],
448/// &['a', 'z'],
449/// &['b', 'z'],
450/// &['c', 'x'],
451/// &['c', 'y'],
452/// &['c', 'z']
453/// ]
454/// );
455/// ```
456///
457/// # exhaustive_vecs_fixed_length_2_inputs
458/// ```
459/// use itertools::Itertools;
460/// use malachite_base::chars::exhaustive::exhaustive_ascii_chars;
461/// use malachite_base::iterators::bit_distributor::BitDistributorOutputType;
462/// use malachite_base::vecs::exhaustive::exhaustive_vecs_fixed_length_2_inputs;
463///
464/// // We are generating length-3 `Vec`s of `char`s using two input iterators. The first iterator
465/// // (with index 0) produces all ASCII `char`s, and the second (index 1) produces the three
466/// // `char`s `'x'`, `'y'`, and `'z'`. The elements of `output_types` have the indices 0, 1, and 0,
467/// // meaning that the first element of the output `Vec`s will be taken from iterator 0, the second
468/// // element from iterator 1, and the third also from iterator 0. The third element has a tiny
469/// // output type, so it will grow more slowly than the other two elements (though it doesn't look
470/// // that way from the first few `Vec`s).
471/// let xss = exhaustive_vecs_fixed_length_2_inputs(
472/// exhaustive_ascii_chars(),
473/// ['x', 'y', 'z'].iter().cloned(),
474/// &[
475/// (BitDistributorOutputType::normal(1), 0),
476/// (BitDistributorOutputType::normal(1), 1),
477/// (BitDistributorOutputType::tiny(), 0),
478/// ],
479/// );
480/// let xss_prefix = xss.take(20).collect_vec();
481/// assert_eq!(
482/// xss_prefix
483/// .iter()
484/// .map(Vec::as_slice)
485/// .collect_vec()
486/// .as_slice(),
487/// &[
488/// &['a', 'x', 'a'],
489/// &['a', 'x', 'b'],
490/// &['a', 'x', 'c'],
491/// &['a', 'x', 'd'],
492/// &['a', 'y', 'a'],
493/// &['a', 'y', 'b'],
494/// &['a', 'y', 'c'],
495/// &['a', 'y', 'd'],
496/// &['a', 'x', 'e'],
497/// &['a', 'x', 'f'],
498/// &['a', 'x', 'g'],
499/// &['a', 'x', 'h'],
500/// &['a', 'y', 'e'],
501/// &['a', 'y', 'f'],
502/// &['a', 'y', 'g'],
503/// &['a', 'y', 'h'],
504/// &['b', 'x', 'a'],
505/// &['b', 'x', 'b'],
506/// &['b', 'x', 'c'],
507/// &['b', 'x', 'd']
508/// ]
509/// );
510/// ```
511pub mod exhaustive;
512#[cfg(feature = "random")]
513/// Iterators that generate [`Vec`]s randomly.
514///
515/// # random_vecs_length_2
516/// ```
517/// use itertools::Itertools;
518/// use malachite_base::chars::random::random_char_inclusive_range;
519/// use malachite_base::random::EXAMPLE_SEED;
520/// use malachite_base::vecs::random::random_vecs_length_2;
521///
522/// let xss = random_vecs_length_2(
523/// EXAMPLE_SEED,
524/// &|seed| random_char_inclusive_range(seed, 'a', 'c'),
525/// &|seed| random_char_inclusive_range(seed, 'x', 'z'),
526/// )
527/// .take(20)
528/// .collect_vec();
529/// assert_eq!(
530/// xss.iter().map(Vec::as_slice).collect_vec().as_slice(),
531/// &[
532/// &['b', 'z'],
533/// &['b', 'x'],
534/// &['b', 'z'],
535/// &['b', 'y'],
536/// &['c', 'x'],
537/// &['a', 'z'],
538/// &['a', 'z'],
539/// &['a', 'z'],
540/// &['c', 'z'],
541/// &['a', 'y'],
542/// &['c', 'x'],
543/// &['a', 'x'],
544/// &['c', 'z'],
545/// &['a', 'z'],
546/// &['c', 'x'],
547/// &['c', 'x'],
548/// &['c', 'y'],
549/// &['b', 'y'],
550/// &['a', 'x'],
551/// &['c', 'x']
552/// ]
553/// );
554/// ```
555///
556/// # random_vecs_fixed_length_2_inputs
557/// ```
558/// use itertools::Itertools;
559/// use malachite_base::chars::random::{random_ascii_chars, random_char_inclusive_range};
560/// use malachite_base::random::EXAMPLE_SEED;
561/// use malachite_base::vecs::random::random_vecs_fixed_length_2_inputs;
562///
563/// // We are generating length-3 `Vec`s of `char`s using two input iterators. The first iterator
564/// // (with index 0) produces random ASCII `char`s, and the second (index 1) produces the three
565/// // `char`s `'x'`, `'y'`, and `'z'`, uniformly at random. The elements of `output_types` are 0,
566/// // 1, and 0, meaning that the first element of the output `Vec`s will be taken from iterator 0,
567/// // the second element from iterator 1, and the third also from iterator 0.
568/// let xss = random_vecs_fixed_length_2_inputs(
569/// EXAMPLE_SEED,
570/// &random_ascii_chars,
571/// &|seed| random_char_inclusive_range(seed, 'x', 'z'),
572/// &[0, 1, 0],
573/// )
574/// .take(20)
575/// .collect_vec();
576/// assert_eq!(
577/// xss.iter().map(Vec::as_slice).collect_vec().as_slice(),
578/// &[
579/// &['U', 'z', '\u{16}'],
580/// &[' ', 'x', 'D'],
581/// &['<', 'z', ']'],
582/// &['a', 'y', 'e'],
583/// &['_', 'x', 'M'],
584/// &[',', 'z', 'O'],
585/// &['\u{1d}', 'z', 'V'],
586/// &['(', 'z', '\u{10}'],
587/// &['&', 'z', 'U'],
588/// &['{', 'y', 'P'],
589/// &['-', 'x', 'K'],
590/// &['Z', 'x', '\u{4}'],
591/// &['X', 'z', '\u{19}'],
592/// &['_', 'z', ','],
593/// &['\u{1d}', 'x', ','],
594/// &['?', 'x', '\''],
595/// &['[', 'y', 'N'],
596/// &['|', 'y', '}'],
597/// &['*', 'x', '\u{15}'],
598/// &['z', 'x', 't']
599/// ]
600/// );
601/// ```
602pub mod random;