malachite_base/vecs/mod.rs
1// Copyright © 2025 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) = O(n + m)$
30///
31/// $M(n) = O(n + m)$
32///
33/// where $T$ is time, $M$ is additional memory, $n$ = `xs.len()` before the function is called, and
34/// $m$ = `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) = O(\operatorname{max}(1, n - m))$
58///
59/// $M(n) = O(1)$
60///
61/// where $T$ is time, $M$ is additional memory, $n$ = `xs.len()` before the function is called, and
62/// $m$ = `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/// # Examples
255/// ```
256/// use itertools::Itertools;
257/// use malachite_base::vecs::exhaustive_vec_permutations;
258///
259/// let css: Vec<String> = exhaustive_vec_permutations(vec!['a', 'b', 'c', 'd'])
260/// .map(|ds| ds.into_iter().collect())
261/// .collect();
262/// assert_eq!(
263/// css.iter().map(String::as_str).collect_vec().as_slice(),
264/// [
265/// "abcd", "abdc", "acbd", "acdb", "adbc", "adcb", "bacd", "badc", "bcad", "bcda", "bdac",
266/// "bdca", "cabd", "cadb", "cbad", "cbda", "cdab", "cdba", "dabc", "dacb", "dbac", "dbca",
267/// "dcab", "dcba"
268/// ]
269/// );
270/// ```
271pub fn exhaustive_vec_permutations<T: Clone>(xs: Vec<T>) -> ExhaustiveVecPermutations<T> {
272 let len = xs.len();
273 ExhaustiveVecPermutations {
274 xs,
275 indices: (0..len).collect(),
276 done: false,
277 }
278}
279
280#[cfg(feature = "random")]
281/// Uniformly generates a random [`Vec`] of values cloned from an original [`Vec`].
282///
283/// This `struct` is created by [`random_vec_permutations`]; see its documentation for more.
284#[derive(Clone, Debug)]
285pub struct RandomVecPermutations<T: Clone> {
286 xs: Vec<T>,
287 indices: Vec<usize>,
288 rng: ChaCha20Rng,
289}
290
291#[cfg(feature = "random")]
292impl<T: Clone> Iterator for RandomVecPermutations<T> {
293 type Item = Vec<T>;
294
295 fn next(&mut self) -> Option<Vec<T>> {
296 self.indices.shuffle(&mut self.rng);
297 Some(self.indices.iter().map(|&i| self.xs[i].clone()).collect())
298 }
299}
300
301#[cfg(feature = "random")]
302/// Uniformly generates a random [`Vec`] of values cloned from an original [`Vec`].
303///
304/// The permutations are [`Vec`]s of cloned items. It may be more convenient for the iterator to
305/// return references to a slice, in which case you may use
306/// [`random_slice_permutations`](crate::slices::random_slice_permutations) instead.
307///
308/// The output length is infinite.
309///
310/// $P(p) = 1/n!$, where $n$ is `xs.len()`.
311///
312/// # Examples
313/// ```
314/// use itertools::Itertools;
315/// use malachite_base::random::EXAMPLE_SEED;
316/// use malachite_base::vecs::random_vec_permutations;
317///
318/// let css: Vec<String> = random_vec_permutations(EXAMPLE_SEED, vec!['a', 'b', 'c', 'd'])
319/// .take(20)
320/// .map(|ds| ds.into_iter().collect())
321/// .collect();
322/// assert_eq!(
323/// css.iter().map(String::as_str).collect_vec().as_slice(),
324/// [
325/// "cadb", "cbad", "cadb", "badc", "acdb", "cbad", "dabc", "dbca", "cdba", "cdab", "bacd",
326/// "cabd", "adbc", "cdab", "dcab", "abcd", "abcd", "dacb", "bcad", "adcb"
327/// ]
328/// );
329/// ```
330pub fn random_vec_permutations<T: Clone>(seed: Seed, xs: Vec<T>) -> RandomVecPermutations<T> {
331 let len = xs.len();
332 RandomVecPermutations {
333 xs,
334 indices: (0..len).collect(),
335 rng: seed.get_rng(),
336 }
337}
338
339/// Iterators that generate [`Vec`]s without repetition.
340///
341/// # lex_vecs_length_2
342/// ```
343/// use itertools::Itertools;
344/// use malachite_base::vecs::exhaustive::lex_vecs_length_2;
345///
346/// let xss = lex_vecs_length_2(
347/// ['a', 'b', 'c'].iter().cloned(),
348/// ['x', 'y', 'z'].iter().cloned(),
349/// )
350/// .collect_vec();
351/// assert_eq!(
352/// xss.iter().map(Vec::as_slice).collect_vec().as_slice(),
353/// &[
354/// &['a', 'x'],
355/// &['a', 'y'],
356/// &['a', 'z'],
357/// &['b', 'x'],
358/// &['b', 'y'],
359/// &['b', 'z'],
360/// &['c', 'x'],
361/// &['c', 'y'],
362/// &['c', 'z']
363/// ]
364/// );
365/// ```
366///
367/// # lex_vecs_fixed_length_2_inputs
368/// ```
369/// use itertools::Itertools;
370/// use malachite_base::chars::exhaustive::exhaustive_ascii_chars;
371/// use malachite_base::vecs::exhaustive::lex_vecs_fixed_length_2_inputs;
372///
373/// // We are generating length-3 `Vec`s of `char`s using two input iterators. The first iterator
374/// // (with index 0) produces all ASCII `char`s, and the second (index 1) produces the three
375/// // `char`s `'x'`, `'y'`, and `'z'`. The elements of `output_types` are 0, 1, and 0, meaning that
376/// // the first element of the output `Vec`s will be taken from iterator 0, the second element from
377/// // iterator 1, and the third also from iterator 0.
378/// let xss = lex_vecs_fixed_length_2_inputs(
379/// exhaustive_ascii_chars(),
380/// ['x', 'y', 'z'].iter().cloned(),
381/// &[0, 1, 0],
382/// );
383/// let xss_prefix = xss.take(20).collect_vec();
384/// assert_eq!(
385/// xss_prefix
386/// .iter()
387/// .map(Vec::as_slice)
388/// .collect_vec()
389/// .as_slice(),
390/// &[
391/// &['a', 'x', 'a'],
392/// &['a', 'x', 'b'],
393/// &['a', 'x', 'c'],
394/// &['a', 'x', 'd'],
395/// &['a', 'x', 'e'],
396/// &['a', 'x', 'f'],
397/// &['a', 'x', 'g'],
398/// &['a', 'x', 'h'],
399/// &['a', 'x', 'i'],
400/// &['a', 'x', 'j'],
401/// &['a', 'x', 'k'],
402/// &['a', 'x', 'l'],
403/// &['a', 'x', 'm'],
404/// &['a', 'x', 'n'],
405/// &['a', 'x', 'o'],
406/// &['a', 'x', 'p'],
407/// &['a', 'x', 'q'],
408/// &['a', 'x', 'r'],
409/// &['a', 'x', 's'],
410/// &['a', 'x', 't']
411/// ]
412/// );
413/// ```
414///
415/// # exhaustive_vecs_length_2
416/// ```
417/// use itertools::Itertools;
418/// use malachite_base::vecs::exhaustive::exhaustive_vecs_length_2;
419///
420/// let xss = exhaustive_vecs_length_2(
421/// ['a', 'b', 'c'].iter().cloned(),
422/// ['x', 'y', 'z'].iter().cloned(),
423/// )
424/// .collect_vec();
425/// assert_eq!(
426/// xss.iter().map(Vec::as_slice).collect_vec().as_slice(),
427/// &[
428/// &['a', 'x'],
429/// &['a', 'y'],
430/// &['b', 'x'],
431/// &['b', 'y'],
432/// &['a', 'z'],
433/// &['b', 'z'],
434/// &['c', 'x'],
435/// &['c', 'y'],
436/// &['c', 'z']
437/// ]
438/// );
439/// ```
440///
441/// # exhaustive_vecs_fixed_length_2_inputs
442/// ```
443/// use itertools::Itertools;
444/// use malachite_base::chars::exhaustive::exhaustive_ascii_chars;
445/// use malachite_base::iterators::bit_distributor::BitDistributorOutputType;
446/// use malachite_base::vecs::exhaustive::exhaustive_vecs_fixed_length_2_inputs;
447///
448/// // We are generating length-3 `Vec`s of `char`s using two input iterators. The first iterator
449/// // (with index 0) produces all ASCII `char`s, and the second (index 1) produces the three
450/// // `char`s `'x'`, `'y'`, and `'z'`. The elements of `output_types` have the indices 0, 1, and 0,
451/// // meaning that the first element of the output `Vec`s will be taken from iterator 0, the second
452/// // element from iterator 1, and the third also from iterator 0. The third element has a tiny
453/// // output type, so it will grow more slowly than the other two elements (though it doesn't look
454/// // that way from the first few `Vec`s).
455/// let xss = exhaustive_vecs_fixed_length_2_inputs(
456/// exhaustive_ascii_chars(),
457/// ['x', 'y', 'z'].iter().cloned(),
458/// &[
459/// (BitDistributorOutputType::normal(1), 0),
460/// (BitDistributorOutputType::normal(1), 1),
461/// (BitDistributorOutputType::tiny(), 0),
462/// ],
463/// );
464/// let xss_prefix = xss.take(20).collect_vec();
465/// assert_eq!(
466/// xss_prefix
467/// .iter()
468/// .map(Vec::as_slice)
469/// .collect_vec()
470/// .as_slice(),
471/// &[
472/// &['a', 'x', 'a'],
473/// &['a', 'x', 'b'],
474/// &['a', 'x', 'c'],
475/// &['a', 'x', 'd'],
476/// &['a', 'y', 'a'],
477/// &['a', 'y', 'b'],
478/// &['a', 'y', 'c'],
479/// &['a', 'y', 'd'],
480/// &['a', 'x', 'e'],
481/// &['a', 'x', 'f'],
482/// &['a', 'x', 'g'],
483/// &['a', 'x', 'h'],
484/// &['a', 'y', 'e'],
485/// &['a', 'y', 'f'],
486/// &['a', 'y', 'g'],
487/// &['a', 'y', 'h'],
488/// &['b', 'x', 'a'],
489/// &['b', 'x', 'b'],
490/// &['b', 'x', 'c'],
491/// &['b', 'x', 'd']
492/// ]
493/// );
494/// ```
495pub mod exhaustive;
496#[cfg(feature = "random")]
497/// Iterators that generate [`Vec`]s randomly.
498///
499/// # random_vecs_length_2
500/// ```
501/// use itertools::Itertools;
502/// use malachite_base::chars::random::random_char_inclusive_range;
503/// use malachite_base::random::EXAMPLE_SEED;
504/// use malachite_base::vecs::random::random_vecs_length_2;
505///
506/// let xss = random_vecs_length_2(
507/// EXAMPLE_SEED,
508/// &|seed| random_char_inclusive_range(seed, 'a', 'c'),
509/// &|seed| random_char_inclusive_range(seed, 'x', 'z'),
510/// )
511/// .take(20)
512/// .collect_vec();
513/// assert_eq!(
514/// xss.iter().map(Vec::as_slice).collect_vec().as_slice(),
515/// &[
516/// &['b', 'z'],
517/// &['b', 'x'],
518/// &['b', 'z'],
519/// &['b', 'y'],
520/// &['c', 'x'],
521/// &['a', 'z'],
522/// &['a', 'z'],
523/// &['a', 'z'],
524/// &['c', 'z'],
525/// &['a', 'y'],
526/// &['c', 'x'],
527/// &['a', 'x'],
528/// &['c', 'z'],
529/// &['a', 'z'],
530/// &['c', 'x'],
531/// &['c', 'x'],
532/// &['c', 'y'],
533/// &['b', 'y'],
534/// &['a', 'x'],
535/// &['c', 'x']
536/// ]
537/// );
538/// ```
539///
540/// # random_vecs_fixed_length_2_inputs
541/// ```
542/// use itertools::Itertools;
543/// use malachite_base::chars::random::{random_ascii_chars, random_char_inclusive_range};
544/// use malachite_base::random::EXAMPLE_SEED;
545/// use malachite_base::vecs::random::random_vecs_fixed_length_2_inputs;
546///
547/// // We are generating length-3 `Vec`s of `char`s using two input iterators. The first iterator
548/// // (with index 0) produces random ASCII `char`s, and the second (index 1) produces the three
549/// // `char`s `'x'`, `'y'`, and `'z'`, uniformly at random. The elements of `output_types` are 0,
550/// // 1, and 0, meaning that the first element of the output `Vec`s will be taken from iterator 0,
551/// // the second element from iterator 1, and the third also from iterator 0.
552/// let xss = random_vecs_fixed_length_2_inputs(
553/// EXAMPLE_SEED,
554/// &random_ascii_chars,
555/// &|seed| random_char_inclusive_range(seed, 'x', 'z'),
556/// &[0, 1, 0],
557/// )
558/// .take(20)
559/// .collect_vec();
560/// assert_eq!(
561/// xss.iter().map(Vec::as_slice).collect_vec().as_slice(),
562/// &[
563/// &['U', 'z', '\u{16}'],
564/// &[' ', 'x', 'D'],
565/// &['<', 'z', ']'],
566/// &['a', 'y', 'e'],
567/// &['_', 'x', 'M'],
568/// &[',', 'z', 'O'],
569/// &['\u{1d}', 'z', 'V'],
570/// &['(', 'z', '\u{10}'],
571/// &['&', 'z', 'U'],
572/// &['{', 'y', 'P'],
573/// &['-', 'x', 'K'],
574/// &['Z', 'x', '\u{4}'],
575/// &['X', 'z', '\u{19}'],
576/// &['_', 'z', ','],
577/// &['\u{1d}', 'x', ','],
578/// &['?', 'x', '\''],
579/// &['[', 'y', 'N'],
580/// &['|', 'y', '}'],
581/// &['*', 'x', '\u{15}'],
582/// &['z', 'x', 't']
583/// ]
584/// );
585/// ```
586pub mod random;