Skip to main content

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;