malachite_base/maps/random.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::conversion::traits::ExactFrom;
10use crate::num::random::geometric::{
11 GeometricRandomNaturalValues, geometric_random_unsigned_inclusive_range,
12 geometric_random_unsigneds,
13};
14use crate::num::random::{
15 RandomUnsignedInclusiveRange, RandomUnsignedRange, VariableRangeGenerator,
16 random_unsigned_inclusive_range, random_unsigned_range,
17};
18use crate::random::Seed;
19#[cfg(not(feature = "std"))]
20use alloc::collections::BTreeMap;
21use core::cmp::{max, min};
22use core::hash::Hash;
23#[cfg(not(feature = "std"))]
24use hashbrown::{HashMap, HashSet};
25#[cfg(feature = "std")]
26use std::collections::{BTreeMap, HashMap, HashSet};
27
28/// Generates random [`BTreeMap`]s of a fixed size.
29///
30/// This `struct` is created by [`random_b_tree_maps_fixed_size`]; see its documentation for more.
31#[derive(Clone, Debug)]
32pub struct RandomBTreeMapsFixedSize<I: Iterator, J: Iterator>
33where
34 I::Item: Ord,
35{
36 size: usize,
37 keys: I,
38 values: J,
39}
40
41impl<I: Iterator, J: Iterator> Iterator for RandomBTreeMapsFixedSize<I, J>
42where
43 I::Item: Ord,
44{
45 type Item = BTreeMap<I::Item, J::Item>;
46
47 fn next(&mut self) -> Option<BTreeMap<I::Item, J::Item>> {
48 let mut map = BTreeMap::new();
49 while map.len() < self.size {
50 // A repeated key costs a key draw but no value draw, so exactly one value is consumed
51 // per entry, paired with its key in the order the keys are drawn rather than in the
52 // map's own order. The [`HashMap`] versions must do this to be reproducible, and these
53 // match them.
54 let key = self.keys.next().unwrap();
55 map.entry(key)
56 .or_insert_with(|| self.values.next().unwrap());
57 }
58 Some(map)
59 }
60}
61
62/// Generates random [`BTreeMap`]s of a given size, with keys from one iterator and values from
63/// another.
64///
65/// The key iterator must generate at least `size` distinct elements; otherwise, this iterator will
66/// hang. The value iterator has no such requirement, since values may repeat.
67///
68/// $$
69/// P(\\{(k_i, v_i)\\}_ {i=0}^{n-1}) = n!\prod_ {i=0}^{n-1}P(k_i)P(v_i).
70/// $$
71///
72/// The above formula assumes that the map is valid, \emph{i.e.} its keys are distinct. The $n!$
73/// counts the orders in which the keys can be drawn; the values are drawn in the same order, so
74/// each key order pairs with exactly one value order that produces the map.
75///
76/// If `size` is 0, the output consists of the empty map, repeated.
77///
78/// `keys` and `values` must be infinite.
79///
80/// # Expected complexity per iteration
81/// $T(i) = O(n (T^\prime(i) + T^{\prime\prime}(i)))$
82///
83/// $M(i) = O(n (M^\prime(i) + M^{\prime\prime}(i)))$
84///
85/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
86/// $M^\prime$ are the time and memory functions of `keys`, $T^{\prime\prime}$ and
87/// $M^{\prime\prime}$ are those of `values`, and $n$ is `size`.
88///
89/// # Examples
90/// ```
91/// use itertools::Itertools;
92/// use malachite_base::chars::random::random_char_inclusive_range;
93/// use malachite_base::maps::random::random_b_tree_maps_fixed_size;
94/// use malachite_base::num::random::random_unsigned_inclusive_range;
95/// use malachite_base::random::EXAMPLE_SEED;
96/// use maplit::btreemap;
97///
98/// let xs = random_b_tree_maps_fixed_size(
99/// 2,
100/// random_char_inclusive_range(EXAMPLE_SEED.fork("keys"), 'a', 'c'),
101/// random_unsigned_inclusive_range::<u8>(EXAMPLE_SEED.fork("values"), 0, 2),
102/// );
103/// let values = xs.take(10).collect_vec();
104/// assert_eq!(
105/// values,
106/// &[
107/// btreemap! {'a' => 0, 'b' => 1},
108/// btreemap! {'a' => 2, 'b' => 0},
109/// btreemap! {'a' => 0, 'b' => 0},
110/// btreemap! {'a' => 2, 'c' => 0},
111/// btreemap! {'a' => 0, 'c' => 0},
112/// btreemap! {'a' => 0, 'c' => 1},
113/// btreemap! {'a' => 2, 'b' => 1},
114/// btreemap! {'b' => 1, 'c' => 2},
115/// btreemap! {'a' => 2, 'c' => 0},
116/// btreemap! {'b' => 0, 'c' => 1}
117/// ]
118/// );
119/// ```
120#[inline]
121pub fn random_b_tree_maps_fixed_size<I: Iterator, J: Iterator>(
122 size: u64,
123 keys: I,
124 values: J,
125) -> RandomBTreeMapsFixedSize<I, J>
126where
127 I::Item: Ord,
128{
129 RandomBTreeMapsFixedSize {
130 size: usize::exact_from(size),
131 keys,
132 values,
133 }
134}
135
136/// Generates random [`BTreeMap`]s with sizes from an iterator.
137#[derive(Clone, Debug)]
138pub struct RandomBTreeMaps<
139 K: Ord,
140 V,
141 I: Iterator<Item = u64>,
142 J: Iterator<Item = K>,
143 L: Iterator<Item = V>,
144> {
145 sizes: I,
146 keys: J,
147 values: L,
148}
149
150impl<K: Ord, V, I: Iterator<Item = u64>, J: Iterator<Item = K>, L: Iterator<Item = V>> Iterator
151 for RandomBTreeMaps<K, V, I, J, L>
152{
153 type Item = BTreeMap<K, V>;
154
155 fn next(&mut self) -> Option<BTreeMap<K, V>> {
156 let size = usize::exact_from(self.sizes.next().unwrap());
157 let mut map = BTreeMap::new();
158 while map.len() < size {
159 // A repeated key costs a key draw but no value draw, so exactly one value is consumed
160 // per entry, paired with its key in the order the keys are drawn rather than in the
161 // map's own order. The [`HashMap`] versions must do this to be reproducible, and these
162 // match them.
163 let key = self.keys.next().unwrap();
164 map.entry(key)
165 .or_insert_with(|| self.values.next().unwrap());
166 }
167 Some(map)
168 }
169}
170
171/// Generates random [`BTreeMap`]s with keys from one iterator, values from another, and sizes from
172/// a third.
173///
174/// The key iterator must generate at least as many distinct elements as any size that is requested;
175/// otherwise, this iterator will hang. The value iterator has no such requirement, since values may
176/// repeat.
177///
178/// $$
179/// P(\\{(k_i, v_i)\\}_ {i=0}^{n-1}) = n!P(n)\prod_ {i=0}^{n-1}P(k_i)P(v_i).
180/// $$
181///
182/// The above formula assumes that the map is valid, \emph{i.e.} its keys are distinct. The $n!$
183/// counts the orders in which the keys can be drawn; the values are drawn in the same order, so
184/// each key order pairs with exactly one value order that produces the map.
185///
186/// `keys_gen` and `values_gen` must produce infinite iterators.
187///
188/// # Expected complexity per iteration
189/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
190///
191/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
192///
193/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
194/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
195/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
196/// and $m$ is the mean size.
197///
198/// # Examples
199/// ```
200/// use itertools::Itertools;
201/// use malachite_base::maps::random::random_b_tree_maps_from_size_iterator;
202/// use malachite_base::num::random::geometric::geometric_random_unsigneds;
203/// use malachite_base::num::random::random_primitive_ints;
204/// use malachite_base::random::EXAMPLE_SEED;
205/// use maplit::btreemap;
206///
207/// let xs = random_b_tree_maps_from_size_iterator(
208/// EXAMPLE_SEED,
209/// &|seed| geometric_random_unsigneds::<u64>(seed, 2, 1),
210/// &random_primitive_ints::<u8>,
211/// &random_primitive_ints::<u8>,
212/// );
213/// let values = xs.take(10).collect_vec();
214/// assert_eq!(
215/// values,
216/// &[
217/// btreemap! {},
218/// btreemap! {},
219/// btreemap! {51 => 64, 79 => 36, 80 => 32},
220/// btreemap! {},
221/// btreemap! {10 => 158},
222/// btreemap! {59 => 39},
223/// btreemap! {160 => 91, 246 => 8, 253 => 71},
224/// btreemap! {245 => 18},
225/// btreemap! {53 => 243, 85 => 220, 139 => 67, 214 => 153, 219 => 134},
226/// btreemap! {233 => 107}
227/// ]
228/// );
229/// ```
230pub fn random_b_tree_maps_from_size_iterator<
231 K: Ord,
232 V,
233 I: Iterator<Item = u64>,
234 J: Iterator<Item = K>,
235 L: Iterator<Item = V>,
236>(
237 seed: Seed,
238 sizes_gen: &dyn Fn(Seed) -> I,
239 keys_gen: &dyn Fn(Seed) -> J,
240 values_gen: &dyn Fn(Seed) -> L,
241) -> RandomBTreeMaps<K, V, I, J, L> {
242 RandomBTreeMaps {
243 sizes: sizes_gen(seed.fork("sizes")),
244 keys: keys_gen(seed.fork("keys")),
245 values: values_gen(seed.fork("values")),
246 }
247}
248
249/// Generates random [`BTreeMap`]s with keys from one iterator and values from another.
250///
251/// The sizes of the maps are sampled from a geometric distribution with a specified mean $m$, equal
252/// to `mean_size_numerator / mean_size_denominator`. $m$ must be greater than 0.
253///
254/// The key iterator must generate at least as many distinct elements as any size that is requested;
255/// otherwise, this iterator will hang. The value iterator has no such requirement, since values may
256/// repeat.
257///
258/// $$
259/// P(\\{(k_i, v_i)\\}_ {i=0}^{n-1}) = n!P(n)\prod_ {i=0}^{n-1}P(k_i)P(v_i).
260/// $$
261///
262/// The above formula assumes that the map is valid, \emph{i.e.} its keys are distinct. The $n!$
263/// counts the orders in which the keys can be drawn; the values are drawn in the same order, so
264/// each key order pairs with exactly one value order that produces the map.
265///
266/// `keys_gen` and `values_gen` must produce infinite iterators.
267///
268/// # Expected complexity per iteration
269/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
270///
271/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
272///
273/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
274/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
275/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
276/// and $m$ is the mean size.
277///
278/// # Panics
279/// Panics if `mean_size_numerator` or `mean_size_denominator` are zero, or, if after being reduced
280/// to lowest terms, their sum is greater than or equal to $2^{64}$.
281///
282/// # Examples
283/// ```
284/// use itertools::Itertools;
285/// use malachite_base::bools::random::random_bools;
286/// use malachite_base::maps::random::random_b_tree_maps;
287/// use malachite_base::num::random::random_unsigned_inclusive_range;
288/// use malachite_base::random::EXAMPLE_SEED;
289/// use maplit::btreemap;
290///
291/// let xs = random_b_tree_maps(
292/// EXAMPLE_SEED,
293/// &|seed| random_unsigned_inclusive_range::<u32>(seed, 1, 100),
294/// &random_bools,
295/// 1,
296/// 1,
297/// );
298/// let values = xs.take(20).collect_vec();
299/// assert_eq!(
300/// values,
301/// &[
302/// btreemap! {},
303/// btreemap! {},
304/// btreemap! {33 => false, 78 => true, 80 => false, 82 => false},
305/// btreemap! {},
306/// btreemap! {40 => true, 49 => false},
307/// btreemap! {33 => false, 64 => false},
308/// btreemap! {88 => false},
309/// btreemap! {43 => false, 100 => false},
310/// btreemap! {},
311/// btreemap! {},
312/// btreemap! {},
313/// btreemap! {},
314/// btreemap! {70 => false},
315/// btreemap! {},
316/// btreemap! {6 => false, 74 => true},
317/// btreemap! {94 => false},
318/// btreemap! {},
319/// btreemap! {79 => false},
320/// btreemap! {},
321/// btreemap! {18 => false, 34 => false}
322/// ]
323/// );
324/// ```
325#[inline]
326pub fn random_b_tree_maps<I: Iterator, J: Iterator>(
327 seed: Seed,
328 keys_gen: &dyn Fn(Seed) -> I,
329 values_gen: &dyn Fn(Seed) -> J,
330 mean_size_numerator: u64,
331 mean_size_denominator: u64,
332) -> RandomBTreeMaps<I::Item, J::Item, GeometricRandomNaturalValues<u64>, I, J>
333where
334 I::Item: Ord,
335{
336 random_b_tree_maps_from_size_iterator(
337 seed,
338 &|seed_2| geometric_random_unsigneds(seed_2, mean_size_numerator, mean_size_denominator),
339 keys_gen,
340 values_gen,
341 )
342}
343
344/// Generates random [`BTreeMap`]s with a minimum size, with keys from one iterator and values from
345/// another.
346///
347/// The sizes of the maps are sampled from a geometric distribution with a specified mean $m$, equal
348/// to `mean_size_numerator / mean_size_denominator`. $m$ must be greater than `min_size`.
349///
350/// The key iterator must generate at least as many distinct elements as any size that is requested;
351/// otherwise, this iterator will hang. The value iterator has no such requirement, since values may
352/// repeat.
353///
354/// $$
355/// P(\\{(k_i, v_i)\\}_ {i=0}^{n-1}) = n!P(n)\prod_ {i=0}^{n-1}P(k_i)P(v_i).
356/// $$
357///
358/// The above formula assumes that the map is valid, \emph{i.e.} its keys are distinct. The $n!$
359/// counts the orders in which the keys can be drawn; the values are drawn in the same order, so
360/// each key order pairs with exactly one value order that produces the map.
361///
362/// `keys_gen` and `values_gen` must produce infinite iterators.
363///
364/// # Expected complexity per iteration
365/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
366///
367/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
368///
369/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
370/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
371/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
372/// and $m$ is the mean size.
373///
374/// # Panics
375/// Panics if `mean_size_numerator` or `mean_size_denominator` are zero, if their ratio is less than
376/// or equal to `min_size`, or if they are too large and manipulating them leads to arithmetic
377/// overflow.
378///
379/// # Examples
380/// ```
381/// use itertools::Itertools;
382/// use malachite_base::maps::random::random_b_tree_maps_min_size;
383/// use malachite_base::num::random::{random_primitive_ints, random_unsigned_inclusive_range};
384/// use malachite_base::random::EXAMPLE_SEED;
385/// use maplit::btreemap;
386///
387/// let xs = random_b_tree_maps_min_size(
388/// EXAMPLE_SEED,
389/// 1,
390/// &random_primitive_ints::<u8>,
391/// &|seed| random_unsigned_inclusive_range::<u8>(seed, 0, 2),
392/// 4,
393/// 1,
394/// );
395/// let values = xs.take(10).collect_vec();
396/// assert_eq!(
397/// values,
398/// &[
399/// btreemap! {79 => 0},
400/// btreemap! {10 => 0, 51 => 2, 80 => 1},
401/// btreemap! {59 => 0, 85 => 0, 160 => 0, 245 => 0, 246 => 2, 253 => 0},
402/// btreemap! {53 => 0},
403/// btreemap! {214 => 1, 219 => 2},
404/// btreemap! {120 => 1, 139 => 1, 233 => 2},
405/// btreemap! {33 => 2, 157 => 1, 158 => 0, 161 => 0, 202 => 0, 236 => 1},
406/// btreemap! {19 => 0, 72 => 2, 153 => 1, 155 => 0, 194 => 2},
407/// btreemap! {25 => 1, 68 => 0, 74 => 0, 80 => 2, 97 => 1, 119 => 0, 236 => 1, 252 => 0},
408/// btreemap! {33 => 1, 241 => 2}
409/// ]
410/// );
411/// ```
412#[inline]
413pub fn random_b_tree_maps_min_size<I: Iterator, J: Iterator>(
414 seed: Seed,
415 min_size: u64,
416 keys_gen: &dyn Fn(Seed) -> I,
417 values_gen: &dyn Fn(Seed) -> J,
418 mean_size_numerator: u64,
419 mean_size_denominator: u64,
420) -> RandomBTreeMaps<I::Item, J::Item, GeometricRandomNaturalValues<u64>, I, J>
421where
422 I::Item: Ord,
423{
424 random_b_tree_maps_from_size_iterator(
425 seed,
426 &|seed_2| {
427 geometric_random_unsigned_inclusive_range(
428 seed_2,
429 min_size,
430 u64::MAX,
431 mean_size_numerator,
432 mean_size_denominator,
433 )
434 },
435 keys_gen,
436 values_gen,
437 )
438}
439
440/// Generates random [`BTreeMap`]s with sizes in the half-open interval $[a, b)$, with keys from one
441/// iterator and values from another.
442///
443/// The key iterator must generate at least as many distinct elements as any size that is requested;
444/// otherwise, this iterator will hang. The value iterator has no such requirement, since values may
445/// repeat.
446///
447/// $$
448/// P(\\{(k_i, v_i)\\}_ {i=0}^{n-1}) = n!P(n)\prod_ {i=0}^{n-1}P(k_i)P(v_i).
449/// $$
450///
451/// The above formula assumes that the map is valid, \emph{i.e.} its keys are distinct. The $n!$
452/// counts the orders in which the keys can be drawn; the values are drawn in the same order, so
453/// each key order pairs with exactly one value order that produces the map.
454///
455/// `keys_gen` and `values_gen` must produce infinite iterators.
456///
457/// # Expected complexity per iteration
458/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
459///
460/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
461///
462/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
463/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
464/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
465/// and $m$ is the mean size.
466///
467/// # Panics
468/// Panics if $a \geq b$.
469///
470/// # Examples
471/// ```
472/// use itertools::Itertools;
473/// use malachite_base::chars::random::random_char_inclusive_range;
474/// use malachite_base::maps::random::random_b_tree_maps_size_range;
475/// use malachite_base::num::random::random_unsigned_inclusive_range;
476/// use malachite_base::random::EXAMPLE_SEED;
477/// use maplit::btreemap;
478///
479/// let xs = random_b_tree_maps_size_range(
480/// EXAMPLE_SEED,
481/// 1,
482/// 3,
483/// &|seed| random_char_inclusive_range(seed, 'a', 'c'),
484/// &|seed| random_unsigned_inclusive_range::<u8>(seed, 0, 1),
485/// );
486/// let values = xs.take(20).collect_vec();
487/// assert_eq!(
488/// values,
489/// &[
490/// btreemap! {'a' => 0},
491/// btreemap! {'b' => 0},
492/// btreemap! {'a' => 1, 'b' => 0},
493/// btreemap! {'a' => 1, 'b' => 0},
494/// btreemap! {'a' => 0, 'c' => 0},
495/// btreemap! {'a' => 0, 'c' => 0},
496/// btreemap! {'a' => 0},
497/// btreemap! {'c' => 0},
498/// btreemap! {'a' => 0, 'b' => 1},
499/// btreemap! {'b' => 0, 'c' => 0},
500/// btreemap! {'a' => 0},
501/// btreemap! {'a' => 0, 'c' => 0},
502/// btreemap! {'b' => 0, 'c' => 0},
503/// btreemap! {'b' => 0},
504/// btreemap! {'a' => 0, 'b' => 1},
505/// btreemap! {'c' => 0},
506/// btreemap! {'b' => 1, 'c' => 1},
507/// btreemap! {'b' => 1, 'c' => 1},
508/// btreemap! {'a' => 0},
509/// btreemap! {'c' => 0}
510/// ]
511/// );
512/// ```
513#[inline]
514pub fn random_b_tree_maps_size_range<I: Iterator, J: Iterator>(
515 seed: Seed,
516 a: u64,
517 b: u64,
518 keys_gen: &dyn Fn(Seed) -> I,
519 values_gen: &dyn Fn(Seed) -> J,
520) -> RandomBTreeMaps<I::Item, J::Item, RandomUnsignedRange<u64>, I, J>
521where
522 I::Item: Ord,
523{
524 random_b_tree_maps_from_size_iterator(
525 seed,
526 &|seed_2| random_unsigned_range(seed_2, a, b),
527 keys_gen,
528 values_gen,
529 )
530}
531
532/// Generates random [`BTreeMap`]s with sizes in the closed interval $[a, b]$, with keys from one
533/// iterator and values from another.
534///
535/// The key iterator must generate at least as many distinct elements as any size that is requested;
536/// otherwise, this iterator will hang. The value iterator has no such requirement, since values may
537/// repeat.
538///
539/// $$
540/// P(\\{(k_i, v_i)\\}_ {i=0}^{n-1}) = n!P(n)\prod_ {i=0}^{n-1}P(k_i)P(v_i).
541/// $$
542///
543/// The above formula assumes that the map is valid, \emph{i.e.} its keys are distinct. The $n!$
544/// counts the orders in which the keys can be drawn; the values are drawn in the same order, so
545/// each key order pairs with exactly one value order that produces the map.
546///
547/// `keys_gen` and `values_gen` must produce infinite iterators.
548///
549/// # Expected complexity per iteration
550/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
551///
552/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
553///
554/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
555/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
556/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
557/// and $m$ is the mean size.
558///
559/// # Panics
560/// Panics if $a > b$.
561///
562/// # Examples
563/// ```
564/// use itertools::Itertools;
565/// use malachite_base::chars::random::random_char_inclusive_range;
566/// use malachite_base::maps::random::random_b_tree_maps_size_inclusive_range;
567/// use malachite_base::num::random::random_unsigned_inclusive_range;
568/// use malachite_base::random::EXAMPLE_SEED;
569/// use maplit::btreemap;
570///
571/// let xs = random_b_tree_maps_size_inclusive_range(
572/// EXAMPLE_SEED,
573/// 1,
574/// 2,
575/// &|seed| random_char_inclusive_range(seed, 'a', 'c'),
576/// &|seed| random_unsigned_inclusive_range::<u8>(seed, 0, 1),
577/// );
578/// let values = xs.take(20).collect_vec();
579/// assert_eq!(
580/// values,
581/// &[
582/// btreemap! {'a' => 0},
583/// btreemap! {'b' => 0},
584/// btreemap! {'a' => 1, 'b' => 0},
585/// btreemap! {'a' => 1, 'b' => 0},
586/// btreemap! {'a' => 0, 'c' => 0},
587/// btreemap! {'a' => 0, 'c' => 0},
588/// btreemap! {'a' => 0},
589/// btreemap! {'c' => 0},
590/// btreemap! {'a' => 0, 'b' => 1},
591/// btreemap! {'b' => 0, 'c' => 0},
592/// btreemap! {'a' => 0},
593/// btreemap! {'a' => 0, 'c' => 0},
594/// btreemap! {'b' => 0, 'c' => 0},
595/// btreemap! {'b' => 0},
596/// btreemap! {'a' => 0, 'b' => 1},
597/// btreemap! {'c' => 0},
598/// btreemap! {'b' => 1, 'c' => 1},
599/// btreemap! {'b' => 1, 'c' => 1},
600/// btreemap! {'a' => 0},
601/// btreemap! {'c' => 0}
602/// ]
603/// );
604/// ```
605#[inline]
606pub fn random_b_tree_maps_size_inclusive_range<I: Iterator, J: Iterator>(
607 seed: Seed,
608 a: u64,
609 b: u64,
610 keys_gen: &dyn Fn(Seed) -> I,
611 values_gen: &dyn Fn(Seed) -> J,
612) -> RandomBTreeMaps<I::Item, J::Item, RandomUnsignedInclusiveRange<u64>, I, J>
613where
614 I::Item: Ord,
615{
616 random_b_tree_maps_from_size_iterator(
617 seed,
618 &|seed_2| random_unsigned_inclusive_range(seed_2, a, b),
619 keys_gen,
620 values_gen,
621 )
622}
623
624// Given the inclusive range $[a, b]$ of allowed distinct-value counts and the inclusive range
625// $[\text{size\_a}, \text{size\_b}]$ of allowed sizes, returns the sub-range of sizes for which
626// some allowed count is achievable. A map with $k$ entries has between 1 and $k$ distinct values,
627// or 0 if $k$ is 0, so a size of 0 is compatible only with a count of 0, and a positive size $k$
628// only with a positive count no greater than $k$.
629fn compatible_size_range(size_a: u64, size_b: u64, a: u64, b: u64) -> (u64, u64) {
630 assert!(a <= b, "a must be less than or equal to b. a: {a}, b: {b}");
631 assert!(
632 size_a <= size_b,
633 "size_a must be less than or equal to size_b. size_a: {size_a}, size_b: {size_b}"
634 );
635 let (lo, hi) = if b == 0 {
636 (size_a, 0)
637 } else {
638 (max(size_a, a), size_b)
639 };
640 assert!(
641 lo <= hi,
642 "no map size in [{size_a}, {size_b}] can have a number of distinct values in [{a}, {b}]"
643 );
644 (lo, hi)
645}
646
647/// Generates random [`BTreeMap`]s with a restricted number of distinct values.
648#[derive(Clone, Debug)]
649pub struct RandomBTreeMapsWithUniqueValueCount<
650 K: Ord,
651 V: Clone + Eq + Hash,
652 I: Iterator<Item = u64>,
653 J: Iterator<Item = K>,
654 L: Iterator<Item = V>,
655> {
656 sizes: I,
657 keys: J,
658 values: L,
659 range_generator: VariableRangeGenerator,
660 a: u64,
661 b: u64,
662}
663
664impl<
665 K: Ord,
666 V: Clone + Eq + Hash,
667 I: Iterator<Item = u64>,
668 J: Iterator<Item = K>,
669 L: Iterator<Item = V>,
670> Iterator for RandomBTreeMapsWithUniqueValueCount<K, V, I, J, L>
671{
672 type Item = BTreeMap<K, V>;
673
674 fn next(&mut self) -> Option<BTreeMap<K, V>> {
675 let size = self.sizes.next().unwrap();
676 // A map with `size` entries has between 1 and `size` distinct values, or 0 if `size` is 0.
677 // The size iterator is built so that this range always meets [`self.a`, `self.b`].
678 let count = usize::exact_from(
679 self.range_generator
680 .next_in_inclusive_range::<u64>(max(self.a, min(size, 1)), min(self.b, size)),
681 );
682 let size = usize::exact_from(size);
683 let mut vs = Vec::with_capacity(count);
684 let mut seen = HashSet::with_capacity(count);
685 while vs.len() < count {
686 let value = self.values.next().unwrap();
687 if seen.insert(value.clone()) {
688 vs.push(value);
689 }
690 }
691 // The first `count` keys drawn take the `count` distinct values, one each, so that every
692 // one of them is used; the rest take a uniformly random one of them. The keys are drawn in
693 // random order, so this does not favor any particular position in the map.
694 let mut map = BTreeMap::new();
695 let mut assigned = 0;
696 while map.len() < size {
697 let key = self.keys.next().unwrap();
698 let range_generator = &mut self.range_generator;
699 map.entry(key).or_insert_with(|| {
700 let value = if assigned < count {
701 vs[assigned].clone()
702 } else {
703 vs[range_generator.next_less_than::<usize>(count)].clone()
704 };
705 assigned += 1;
706 value
707 });
708 }
709 Some(map)
710 }
711}
712
713fn random_b_tree_maps_with_unique_value_count_from_size_iterator<
714 K: Ord,
715 V: Clone + Eq + Hash,
716 I: Iterator<Item = u64>,
717 J: Iterator<Item = K>,
718 L: Iterator<Item = V>,
719>(
720 seed: Seed,
721 sizes_gen: &dyn Fn(Seed) -> I,
722 keys_gen: &dyn Fn(Seed) -> J,
723 values_gen: &dyn Fn(Seed) -> L,
724 a: u64,
725 b: u64,
726) -> RandomBTreeMapsWithUniqueValueCount<K, V, I, J, L> {
727 RandomBTreeMapsWithUniqueValueCount {
728 sizes: sizes_gen(seed.fork("sizes")),
729 keys: keys_gen(seed.fork("keys")),
730 values: values_gen(seed.fork("values")),
731 range_generator: VariableRangeGenerator::new(seed.fork("unique_value_counts")),
732 a,
733 b,
734 }
735}
736
737/// Generates random [`BTreeMap`]s with a given number of distinct values, with keys from one
738/// iterator and values from another.
739///
740/// The key iterator must generate at least as many distinct elements as any size that is requested,
741/// and the value iterator at least as many distinct elements as any number of distinct values that
742/// is requested; otherwise, this iterator will hang.
743///
744/// $$
745/// P(m) = P(n)P(d)d!(n-d)!\frac{\prod_{j=0}^{d-1}c_j}{d^{n-d}}
746/// \prod_{i=0}^{n-1}P(k_i)\prod_{j=0}^{d-1}P(w_j).
747/// $$
748///
749/// Here the map $m$ has $n$ entries $(k_i, v_i)$ and $d$ distinct values $w_0, \ldots, w_{d-1}$,
750/// the $j$th of which is the value of $c_j$ of the entries; $P(n)$ is the probability of drawing
751/// the size $n$, and $P(d)$ that of drawing the distinct-value count $d$, which is uniform over the
752/// counts that a size-$n$ map is allowed to have. The formula assumes that the map is valid,
753/// \emph{i.e.} its keys are distinct and it has exactly $d$ distinct values. Maps with the same $n$
754/// and $d$ are not equally likely: the $\prod_j c_j$ factor favors those whose values are spread
755/// evenly over the keys.
756///
757/// `keys_gen` and `values_gen` must produce infinite iterators.
758///
759/// If `unique_value_count` is 0, the output consists of the empty map, repeated.
760///
761/// # Expected complexity per iteration
762/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
763///
764/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
765///
766/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
767/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
768/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
769/// and $m$ is the mean size.
770///
771/// # Panics
772/// Panics if `mean_size_numerator` or `mean_size_denominator` are zero, if their ratio is less than
773/// or equal to `unique_value_count`, or if they are too large and manipulating them leads to
774/// arithmetic overflow.
775///
776/// # Examples
777/// ```
778/// use itertools::Itertools;
779/// use malachite_base::maps::random::random_b_tree_maps_fixed_unique_value_count;
780/// use malachite_base::num::random::{random_primitive_ints, random_unsigned_inclusive_range};
781/// use malachite_base::random::EXAMPLE_SEED;
782/// use maplit::btreemap;
783///
784/// let xs = random_b_tree_maps_fixed_unique_value_count(
785/// EXAMPLE_SEED,
786/// 1,
787/// &random_primitive_ints::<u8>,
788/// &|seed| random_unsigned_inclusive_range::<u8>(seed, 0, 2),
789/// 2,
790/// 1,
791/// );
792/// let values = xs.take(10).collect_vec();
793/// assert_eq!(
794/// values,
795/// &[
796/// btreemap! {79 => 0},
797/// btreemap! {80 => 1},
798/// btreemap! {10 => 2, 51 => 2, 59 => 2, 246 => 2, 253 => 2},
799/// btreemap! {160 => 0},
800/// btreemap! {53 => 0, 85 => 0, 245 => 0},
801/// btreemap! {139 => 0, 214 => 0, 219 => 0},
802/// btreemap! {120 => 2, 233 => 2},
803/// btreemap! {33 => 0, 158 => 0, 236 => 0},
804/// btreemap! {202 => 0},
805/// btreemap! {157 => 0}
806/// ]
807/// );
808/// ```
809#[inline]
810pub fn random_b_tree_maps_fixed_unique_value_count<I: Iterator, J: Iterator>(
811 seed: Seed,
812 unique_value_count: u64,
813 keys_gen: &dyn Fn(Seed) -> I,
814 values_gen: &dyn Fn(Seed) -> J,
815 mean_size_numerator: u64,
816 mean_size_denominator: u64,
817) -> RandomBTreeMapsWithUniqueValueCount<I::Item, J::Item, GeometricRandomNaturalValues<u64>, I, J>
818where
819 I::Item: Ord,
820 J::Item: Clone + Eq + Hash,
821{
822 random_b_tree_maps_unique_value_count_inclusive_range(
823 seed,
824 unique_value_count,
825 unique_value_count,
826 keys_gen,
827 values_gen,
828 mean_size_numerator,
829 mean_size_denominator,
830 )
831}
832
833/// Generates random [`BTreeMap`]s whose number of distinct values is in the half-open interval $[a,
834/// b)$, with keys from one iterator and values from another.
835///
836/// The key iterator must generate at least as many distinct elements as any size that is requested,
837/// and the value iterator at least as many distinct elements as any number of distinct values that
838/// is requested; otherwise, this iterator will hang.
839///
840/// $$
841/// P(m) = P(n)P(d)d!(n-d)!\frac{\prod_{j=0}^{d-1}c_j}{d^{n-d}}
842/// \prod_{i=0}^{n-1}P(k_i)\prod_{j=0}^{d-1}P(w_j).
843/// $$
844///
845/// Here the map $m$ has $n$ entries $(k_i, v_i)$ and $d$ distinct values $w_0, \ldots, w_{d-1}$,
846/// the $j$th of which is the value of $c_j$ of the entries; $P(n)$ is the probability of drawing
847/// the size $n$, and $P(d)$ that of drawing the distinct-value count $d$, which is uniform over the
848/// counts that a size-$n$ map is allowed to have. The formula assumes that the map is valid,
849/// \emph{i.e.} its keys are distinct and it has exactly $d$ distinct values. Maps with the same $n$
850/// and $d$ are not equally likely: the $\prod_j c_j$ factor favors those whose values are spread
851/// evenly over the keys.
852///
853/// `keys_gen` and `values_gen` must produce infinite iterators.
854///
855/// # Expected complexity per iteration
856/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
857///
858/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
859///
860/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
861/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
862/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
863/// and $m$ is the mean size.
864///
865/// # Panics
866/// Panics if $a \geq b$, if `mean_size_numerator` or `mean_size_denominator` are zero, if their
867/// ratio is less than or equal to $a$, or if they are too large and manipulating them leads to
868/// arithmetic overflow.
869///
870/// # Examples
871/// ```
872/// use itertools::Itertools;
873/// use malachite_base::maps::random::random_b_tree_maps_unique_value_count_range;
874/// use malachite_base::num::random::{random_primitive_ints, random_unsigned_inclusive_range};
875/// use malachite_base::random::EXAMPLE_SEED;
876/// use maplit::btreemap;
877///
878/// let xs = random_b_tree_maps_unique_value_count_range(
879/// EXAMPLE_SEED,
880/// 0,
881/// 2,
882/// &random_primitive_ints::<u8>,
883/// &|seed| random_unsigned_inclusive_range::<u8>(seed, 0, 2),
884/// 2,
885/// 1,
886/// );
887/// let values = xs.take(10).collect_vec();
888/// assert_eq!(
889/// values,
890/// &[
891/// btreemap! {},
892/// btreemap! {},
893/// btreemap! {51 => 0, 79 => 0, 80 => 0},
894/// btreemap! {},
895/// btreemap! {10 => 1},
896/// btreemap! {59 => 2},
897/// btreemap! {160 => 0, 246 => 0, 253 => 0},
898/// btreemap! {245 => 0},
899/// btreemap! {53 => 0, 85 => 0, 139 => 0, 214 => 0, 219 => 0},
900/// btreemap! {233 => 2}
901/// ]
902/// );
903/// ```
904#[inline]
905pub fn random_b_tree_maps_unique_value_count_range<I: Iterator, J: Iterator>(
906 seed: Seed,
907 a: u64,
908 b: u64,
909 keys_gen: &dyn Fn(Seed) -> I,
910 values_gen: &dyn Fn(Seed) -> J,
911 mean_size_numerator: u64,
912 mean_size_denominator: u64,
913) -> RandomBTreeMapsWithUniqueValueCount<I::Item, J::Item, GeometricRandomNaturalValues<u64>, I, J>
914where
915 I::Item: Ord,
916 J::Item: Clone + Eq + Hash,
917{
918 assert!(a < b, "a must be less than b. a: {a}, b: {b}");
919 random_b_tree_maps_unique_value_count_inclusive_range(
920 seed,
921 a,
922 b - 1,
923 keys_gen,
924 values_gen,
925 mean_size_numerator,
926 mean_size_denominator,
927 )
928}
929
930/// Generates random [`BTreeMap`]s whose number of distinct values is in the closed interval $[a,
931/// b]$, with keys from one iterator and values from another.
932///
933/// The key iterator must generate at least as many distinct elements as any size that is requested,
934/// and the value iterator at least as many distinct elements as any number of distinct values that
935/// is requested; otherwise, this iterator will hang.
936///
937/// $$
938/// P(m) = P(n)P(d)d!(n-d)!\frac{\prod_{j=0}^{d-1}c_j}{d^{n-d}}
939/// \prod_{i=0}^{n-1}P(k_i)\prod_{j=0}^{d-1}P(w_j).
940/// $$
941///
942/// Here the map $m$ has $n$ entries $(k_i, v_i)$ and $d$ distinct values $w_0, \ldots, w_{d-1}$,
943/// the $j$th of which is the value of $c_j$ of the entries; $P(n)$ is the probability of drawing
944/// the size $n$, and $P(d)$ that of drawing the distinct-value count $d$, which is uniform over the
945/// counts that a size-$n$ map is allowed to have. The formula assumes that the map is valid,
946/// \emph{i.e.} its keys are distinct and it has exactly $d$ distinct values. Maps with the same $n$
947/// and $d$ are not equally likely: the $\prod_j c_j$ factor favors those whose values are spread
948/// evenly over the keys.
949///
950/// `keys_gen` and `values_gen` must produce infinite iterators.
951///
952/// If $b$ is 0, the output consists of the empty map, repeated.
953///
954/// # Expected complexity per iteration
955/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
956///
957/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
958///
959/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
960/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
961/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
962/// and $m$ is the mean size.
963///
964/// # Panics
965/// Panics if $a > b$, if `mean_size_numerator` or `mean_size_denominator` are zero, if their ratio
966/// is less than or equal to $a$, or if they are too large and manipulating them leads to arithmetic
967/// overflow.
968///
969/// # Examples
970/// ```
971/// use itertools::Itertools;
972/// use malachite_base::maps::random::random_b_tree_maps_unique_value_count_inclusive_range;
973/// use malachite_base::num::random::{random_primitive_ints, random_unsigned_inclusive_range};
974/// use malachite_base::random::EXAMPLE_SEED;
975/// use maplit::btreemap;
976///
977/// let xs = random_b_tree_maps_unique_value_count_inclusive_range(
978/// EXAMPLE_SEED,
979/// 0,
980/// 1,
981/// &random_primitive_ints::<u8>,
982/// &|seed| random_unsigned_inclusive_range::<u8>(seed, 0, 2),
983/// 2,
984/// 1,
985/// );
986/// let values = xs.take(10).collect_vec();
987/// assert_eq!(
988/// values,
989/// &[
990/// btreemap! {},
991/// btreemap! {},
992/// btreemap! {51 => 0, 79 => 0, 80 => 0},
993/// btreemap! {},
994/// btreemap! {10 => 1},
995/// btreemap! {59 => 2},
996/// btreemap! {160 => 0, 246 => 0, 253 => 0},
997/// btreemap! {245 => 0},
998/// btreemap! {53 => 0, 85 => 0, 139 => 0, 214 => 0, 219 => 0},
999/// btreemap! {233 => 2}
1000/// ]
1001/// );
1002/// ```
1003pub fn random_b_tree_maps_unique_value_count_inclusive_range<I: Iterator, J: Iterator>(
1004 seed: Seed,
1005 a: u64,
1006 b: u64,
1007 keys_gen: &dyn Fn(Seed) -> I,
1008 values_gen: &dyn Fn(Seed) -> J,
1009 mean_size_numerator: u64,
1010 mean_size_denominator: u64,
1011) -> RandomBTreeMapsWithUniqueValueCount<I::Item, J::Item, GeometricRandomNaturalValues<u64>, I, J>
1012where
1013 I::Item: Ord,
1014 J::Item: Clone + Eq + Hash,
1015{
1016 let (size_a, size_b) = compatible_size_range(0, u64::MAX, a, b);
1017 random_b_tree_maps_with_unique_value_count_from_size_iterator(
1018 seed,
1019 &|seed_2| {
1020 geometric_random_unsigned_inclusive_range(
1021 seed_2,
1022 size_a,
1023 size_b,
1024 mean_size_numerator,
1025 mean_size_denominator,
1026 )
1027 },
1028 keys_gen,
1029 values_gen,
1030 a,
1031 b,
1032 )
1033}
1034
1035/// Generates random [`BTreeMap`]s whose size is in the closed interval $[\text{size\_a},
1036/// \text{size\_b}]$ and whose number of distinct values is in the closed interval
1037/// $[\text{unique\_value\_count\_a}, \text{unique\_value\_count\_b}]$, with keys from one iterator
1038/// and values from another.
1039///
1040/// A map with $k$ entries has between 1 and $k$ distinct values, or 0 if $k$ is 0, so the sizes are
1041/// drawn uniformly not from all of $[\text{size\_a}, \text{size\_b}]$ but from those of its members
1042/// that can have an allowed number of distinct values.
1043///
1044/// The key iterator must generate at least as many distinct elements as any size that is requested,
1045/// and the value iterator at least as many distinct elements as any number of distinct values that
1046/// is requested; otherwise, this iterator will hang.
1047///
1048/// $$
1049/// P(m) = P(n)P(d)d!(n-d)!\frac{\prod_{j=0}^{d-1}c_j}{d^{n-d}}
1050/// \prod_{i=0}^{n-1}P(k_i)\prod_{j=0}^{d-1}P(w_j).
1051/// $$
1052///
1053/// Here the map $m$ has $n$ entries $(k_i, v_i)$ and $d$ distinct values $w_0, \ldots, w_{d-1}$,
1054/// the $j$th of which is the value of $c_j$ of the entries; $P(n)$ is the probability of drawing
1055/// the size $n$, and $P(d)$ that of drawing the distinct-value count $d$, which is uniform over the
1056/// counts that a size-$n$ map is allowed to have. The formula assumes that the map is valid,
1057/// \emph{i.e.} its keys are distinct and it has exactly $d$ distinct values. Maps with the same $n$
1058/// and $d$ are not equally likely: the $\prod_j c_j$ factor favors those whose values are spread
1059/// evenly over the keys.
1060///
1061/// `keys_gen` and `values_gen` must produce infinite iterators.
1062///
1063/// # Expected complexity per iteration
1064/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
1065///
1066/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
1067///
1068/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
1069/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
1070/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
1071/// and $m$ is the mean size.
1072///
1073/// # Panics
1074/// Panics if $\text{size\_a} > \text{size\_b}$, if $\text{unique\_value\_count\_a} >
1075/// \text{unique\_value\_count\_b}$, or if no size in $[\text{size\_a}, \text{size\_b}]$ can have a
1076/// number of distinct values in $[\text{unique\_value\_count\_a}, \text{unique\_value\_count\_b}]$.
1077///
1078/// # Examples
1079/// ```
1080/// use itertools::Itertools;
1081/// use malachite_base::chars::random::random_char_inclusive_range;
1082/// use malachite_base::maps::random::*;
1083/// use malachite_base::num::random::random_unsigned_inclusive_range;
1084/// use malachite_base::random::EXAMPLE_SEED;
1085/// use maplit::btreemap;
1086///
1087/// let xs = random_b_tree_maps_size_and_unique_value_count_inclusive_range(
1088/// EXAMPLE_SEED,
1089/// 2,
1090/// 3,
1091/// 1,
1092/// 2,
1093/// &|seed| random_char_inclusive_range(seed, 'a', 'c'),
1094/// &|seed| random_unsigned_inclusive_range::<u8>(seed, 0, 2),
1095/// );
1096/// let values = xs.take(20).collect_vec();
1097/// assert_eq!(
1098/// values,
1099/// &[
1100/// btreemap! {'a' => 0, 'b' => 1},
1101/// btreemap! {'a' => 2, 'b' => 2},
1102/// btreemap! {'a' => 0, 'b' => 0, 'c' => 0},
1103/// btreemap! {'a' => 2, 'b' => 2, 'c' => 0},
1104/// btreemap! {'a' => 0, 'b' => 0, 'c' => 0},
1105/// btreemap! {'a' => 0, 'b' => 0, 'c' => 0},
1106/// btreemap! {'a' => 0, 'b' => 0},
1107/// btreemap! {'b' => 0, 'c' => 0},
1108/// btreemap! {'a' => 1, 'b' => 1, 'c' => 2},
1109/// btreemap! {'a' => 1, 'b' => 2, 'c' => 1},
1110/// btreemap! {'b' => 2, 'c' => 1},
1111/// btreemap! {'a' => 1, 'b' => 0, 'c' => 1},
1112/// btreemap! {'a' => 0, 'b' => 0, 'c' => 1},
1113/// btreemap! {'a' => 2, 'c' => 0},
1114/// btreemap! {'a' => 0, 'b' => 0, 'c' => 0},
1115/// btreemap! {'b' => 0, 'c' => 2},
1116/// btreemap! {'a' => 1, 'b' => 1, 'c' => 1},
1117/// btreemap! {'a' => 1, 'b' => 1, 'c' => 1},
1118/// btreemap! {'b' => 0, 'c' => 2},
1119/// btreemap! {'a' => 1, 'c' => 1}
1120/// ]
1121/// );
1122/// ```
1123pub fn random_b_tree_maps_size_and_unique_value_count_inclusive_range<I: Iterator, J: Iterator>(
1124 seed: Seed,
1125 size_a: u64,
1126 size_b: u64,
1127 unique_value_count_a: u64,
1128 unique_value_count_b: u64,
1129 keys_gen: &dyn Fn(Seed) -> I,
1130 values_gen: &dyn Fn(Seed) -> J,
1131) -> RandomBTreeMapsWithUniqueValueCount<I::Item, J::Item, RandomUnsignedInclusiveRange<u64>, I, J>
1132where
1133 I::Item: Ord,
1134 J::Item: Clone + Eq + Hash,
1135{
1136 let (lo, hi) =
1137 compatible_size_range(size_a, size_b, unique_value_count_a, unique_value_count_b);
1138 random_b_tree_maps_with_unique_value_count_from_size_iterator(
1139 seed,
1140 &|seed_2| random_unsigned_inclusive_range(seed_2, lo, hi),
1141 keys_gen,
1142 values_gen,
1143 unique_value_count_a,
1144 unique_value_count_b,
1145 )
1146}
1147
1148/// Generates random [`HashMap`]s of a fixed size.
1149///
1150/// This `struct` is created by [`random_hash_maps_fixed_size`]; see its documentation for more.
1151#[derive(Clone, Debug)]
1152pub struct RandomHashMapsFixedSize<I: Iterator, J: Iterator>
1153where
1154 I::Item: Eq + Hash,
1155{
1156 size: usize,
1157 keys: I,
1158 values: J,
1159}
1160
1161impl<I: Iterator, J: Iterator> Iterator for RandomHashMapsFixedSize<I, J>
1162where
1163 I::Item: Eq + Hash,
1164{
1165 type Item = HashMap<I::Item, J::Item>;
1166
1167 fn next(&mut self) -> Option<HashMap<I::Item, J::Item>> {
1168 let mut map = HashMap::new();
1169 while map.len() < self.size {
1170 // A repeated key costs a key draw but no value draw, so exactly one value is consumed
1171 // per entry, paired with its key in the order the keys are drawn. Pairing them by the
1172 // map's own iteration order instead would make the output depend on the hasher, and so
1173 // differ between runs.
1174 let key = self.keys.next().unwrap();
1175 map.entry(key)
1176 .or_insert_with(|| self.values.next().unwrap());
1177 }
1178 Some(map)
1179 }
1180}
1181
1182/// Generates random [`HashMap`]s of a given size, with keys from one iterator and values from
1183/// another.
1184///
1185/// The key iterator must generate at least `size` distinct elements; otherwise, this iterator will
1186/// hang. The value iterator has no such requirement, since values may repeat.
1187///
1188/// $$
1189/// P(\\{(k_i, v_i)\\}_ {i=0}^{n-1}) = n!\prod_ {i=0}^{n-1}P(k_i)P(v_i).
1190/// $$
1191///
1192/// The above formula assumes that the map is valid, \emph{i.e.} its keys are distinct. The $n!$
1193/// counts the orders in which the keys can be drawn; the values are drawn in the same order, so
1194/// each key order pairs with exactly one value order that produces the map.
1195///
1196/// If `size` is 0, the output consists of the empty map, repeated.
1197///
1198/// `keys` and `values` must be infinite.
1199///
1200/// # Expected complexity per iteration
1201/// $T(i) = O(n (T^\prime(i) + T^{\prime\prime}(i)))$
1202///
1203/// $M(i) = O(n (M^\prime(i) + M^{\prime\prime}(i)))$
1204///
1205/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
1206/// $M^\prime$ are the time and memory functions of `keys`, $T^{\prime\prime}$ and
1207/// $M^{\prime\prime}$ are those of `values`, and $n$ is `size`.
1208///
1209/// # Examples
1210/// ```
1211/// use itertools::Itertools;
1212/// use malachite_base::chars::random::random_char_inclusive_range;
1213/// use malachite_base::maps::random::random_hash_maps_fixed_size;
1214/// use malachite_base::num::random::random_unsigned_inclusive_range;
1215/// use malachite_base::random::EXAMPLE_SEED;
1216/// use maplit::hashmap;
1217///
1218/// let xs = random_hash_maps_fixed_size(
1219/// 2,
1220/// random_char_inclusive_range(EXAMPLE_SEED.fork("keys"), 'a', 'c'),
1221/// random_unsigned_inclusive_range::<u8>(EXAMPLE_SEED.fork("values"), 0, 2),
1222/// );
1223/// let values = xs.take(10).collect_vec();
1224/// assert_eq!(
1225/// values,
1226/// &[
1227/// hashmap! {'a' => 0, 'b' => 1},
1228/// hashmap! {'a' => 2, 'b' => 0},
1229/// hashmap! {'a' => 0, 'b' => 0},
1230/// hashmap! {'a' => 2, 'c' => 0},
1231/// hashmap! {'a' => 0, 'c' => 0},
1232/// hashmap! {'a' => 0, 'c' => 1},
1233/// hashmap! {'a' => 2, 'b' => 1},
1234/// hashmap! {'b' => 1, 'c' => 2},
1235/// hashmap! {'a' => 2, 'c' => 0},
1236/// hashmap! {'b' => 0, 'c' => 1}
1237/// ]
1238/// );
1239/// ```
1240#[inline]
1241pub fn random_hash_maps_fixed_size<I: Iterator, J: Iterator>(
1242 size: u64,
1243 keys: I,
1244 values: J,
1245) -> RandomHashMapsFixedSize<I, J>
1246where
1247 I::Item: Eq + Hash,
1248{
1249 RandomHashMapsFixedSize {
1250 size: usize::exact_from(size),
1251 keys,
1252 values,
1253 }
1254}
1255
1256/// Generates random [`HashMap`]s with sizes from an iterator.
1257#[derive(Clone, Debug)]
1258pub struct RandomHashMaps<
1259 K: Eq + Hash,
1260 V,
1261 I: Iterator<Item = u64>,
1262 J: Iterator<Item = K>,
1263 L: Iterator<Item = V>,
1264> {
1265 sizes: I,
1266 keys: J,
1267 values: L,
1268}
1269
1270impl<K: Eq + Hash, V, I: Iterator<Item = u64>, J: Iterator<Item = K>, L: Iterator<Item = V>>
1271 Iterator for RandomHashMaps<K, V, I, J, L>
1272{
1273 type Item = HashMap<K, V>;
1274
1275 fn next(&mut self) -> Option<HashMap<K, V>> {
1276 let size = usize::exact_from(self.sizes.next().unwrap());
1277 let mut map = HashMap::new();
1278 while map.len() < size {
1279 // A repeated key costs a key draw but no value draw, so exactly one value is consumed
1280 // per entry, paired with its key in the order the keys are drawn. Pairing them by the
1281 // map's own iteration order instead would make the output depend on the hasher, and so
1282 // differ between runs.
1283 let key = self.keys.next().unwrap();
1284 map.entry(key)
1285 .or_insert_with(|| self.values.next().unwrap());
1286 }
1287 Some(map)
1288 }
1289}
1290
1291/// Generates random [`HashMap`]s with keys from one iterator, values from another, and sizes from a
1292/// third.
1293///
1294/// The key iterator must generate at least as many distinct elements as any size that is requested;
1295/// otherwise, this iterator will hang. The value iterator has no such requirement, since values may
1296/// repeat.
1297///
1298/// $$
1299/// P(\\{(k_i, v_i)\\}_ {i=0}^{n-1}) = n!P(n)\prod_ {i=0}^{n-1}P(k_i)P(v_i).
1300/// $$
1301///
1302/// The above formula assumes that the map is valid, \emph{i.e.} its keys are distinct. The $n!$
1303/// counts the orders in which the keys can be drawn; the values are drawn in the same order, so
1304/// each key order pairs with exactly one value order that produces the map.
1305///
1306/// `keys_gen` and `values_gen` must produce infinite iterators.
1307///
1308/// # Expected complexity per iteration
1309/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
1310///
1311/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
1312///
1313/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
1314/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
1315/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
1316/// and $m$ is the mean size.
1317///
1318/// # Examples
1319/// ```
1320/// use itertools::Itertools;
1321/// use malachite_base::maps::random::random_hash_maps_from_size_iterator;
1322/// use malachite_base::num::random::geometric::geometric_random_unsigneds;
1323/// use malachite_base::num::random::random_primitive_ints;
1324/// use malachite_base::random::EXAMPLE_SEED;
1325/// use maplit::hashmap;
1326///
1327/// let xs = random_hash_maps_from_size_iterator(
1328/// EXAMPLE_SEED,
1329/// &|seed| geometric_random_unsigneds::<u64>(seed, 2, 1),
1330/// &random_primitive_ints::<u8>,
1331/// &random_primitive_ints::<u8>,
1332/// );
1333/// let values = xs.take(10).collect_vec();
1334/// assert_eq!(
1335/// values,
1336/// &[
1337/// hashmap! {},
1338/// hashmap! {},
1339/// hashmap! {51 => 64, 79 => 36, 80 => 32},
1340/// hashmap! {},
1341/// hashmap! {10 => 158},
1342/// hashmap! {59 => 39},
1343/// hashmap! {160 => 91, 246 => 8, 253 => 71},
1344/// hashmap! {245 => 18},
1345/// hashmap! {53 => 243, 85 => 220, 139 => 67, 214 => 153, 219 => 134},
1346/// hashmap! {233 => 107}
1347/// ]
1348/// );
1349/// ```
1350pub fn random_hash_maps_from_size_iterator<
1351 K: Eq + Hash,
1352 V,
1353 I: Iterator<Item = u64>,
1354 J: Iterator<Item = K>,
1355 L: Iterator<Item = V>,
1356>(
1357 seed: Seed,
1358 sizes_gen: &dyn Fn(Seed) -> I,
1359 keys_gen: &dyn Fn(Seed) -> J,
1360 values_gen: &dyn Fn(Seed) -> L,
1361) -> RandomHashMaps<K, V, I, J, L> {
1362 RandomHashMaps {
1363 sizes: sizes_gen(seed.fork("sizes")),
1364 keys: keys_gen(seed.fork("keys")),
1365 values: values_gen(seed.fork("values")),
1366 }
1367}
1368
1369/// Generates random [`HashMap`]s with keys from one iterator and values from another.
1370///
1371/// The sizes of the maps are sampled from a geometric distribution with a specified mean $m$, equal
1372/// to `mean_size_numerator / mean_size_denominator`. $m$ must be greater than 0.
1373///
1374/// The key iterator must generate at least as many distinct elements as any size that is requested;
1375/// otherwise, this iterator will hang. The value iterator has no such requirement, since values may
1376/// repeat.
1377///
1378/// $$
1379/// P(\\{(k_i, v_i)\\}_ {i=0}^{n-1}) = n!P(n)\prod_ {i=0}^{n-1}P(k_i)P(v_i).
1380/// $$
1381///
1382/// The above formula assumes that the map is valid, \emph{i.e.} its keys are distinct. The $n!$
1383/// counts the orders in which the keys can be drawn; the values are drawn in the same order, so
1384/// each key order pairs with exactly one value order that produces the map.
1385///
1386/// `keys_gen` and `values_gen` must produce infinite iterators.
1387///
1388/// # Expected complexity per iteration
1389/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
1390///
1391/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
1392///
1393/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
1394/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
1395/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
1396/// and $m$ is the mean size.
1397///
1398/// # Panics
1399/// Panics if `mean_size_numerator` or `mean_size_denominator` are zero, or, if after being reduced
1400/// to lowest terms, their sum is greater than or equal to $2^{64}$.
1401///
1402/// # Examples
1403/// ```
1404/// use itertools::Itertools;
1405/// use malachite_base::bools::random::random_bools;
1406/// use malachite_base::maps::random::random_hash_maps;
1407/// use malachite_base::num::random::random_unsigned_inclusive_range;
1408/// use malachite_base::random::EXAMPLE_SEED;
1409/// use maplit::hashmap;
1410///
1411/// let xs = random_hash_maps(
1412/// EXAMPLE_SEED,
1413/// &|seed| random_unsigned_inclusive_range::<u32>(seed, 1, 100),
1414/// &random_bools,
1415/// 1,
1416/// 1,
1417/// );
1418/// let values = xs.take(20).collect_vec();
1419/// assert_eq!(
1420/// values,
1421/// &[
1422/// hashmap! {},
1423/// hashmap! {},
1424/// hashmap! {33 => false, 78 => true, 80 => false, 82 => false},
1425/// hashmap! {},
1426/// hashmap! {40 => true, 49 => false},
1427/// hashmap! {33 => false, 64 => false},
1428/// hashmap! {88 => false},
1429/// hashmap! {43 => false, 100 => false},
1430/// hashmap! {},
1431/// hashmap! {},
1432/// hashmap! {},
1433/// hashmap! {},
1434/// hashmap! {70 => false},
1435/// hashmap! {},
1436/// hashmap! {6 => false, 74 => true},
1437/// hashmap! {94 => false},
1438/// hashmap! {},
1439/// hashmap! {79 => false},
1440/// hashmap! {},
1441/// hashmap! {18 => false, 34 => false}
1442/// ]
1443/// );
1444/// ```
1445#[inline]
1446pub fn random_hash_maps<I: Iterator, J: Iterator>(
1447 seed: Seed,
1448 keys_gen: &dyn Fn(Seed) -> I,
1449 values_gen: &dyn Fn(Seed) -> J,
1450 mean_size_numerator: u64,
1451 mean_size_denominator: u64,
1452) -> RandomHashMaps<I::Item, J::Item, GeometricRandomNaturalValues<u64>, I, J>
1453where
1454 I::Item: Eq + Hash,
1455{
1456 random_hash_maps_from_size_iterator(
1457 seed,
1458 &|seed_2| geometric_random_unsigneds(seed_2, mean_size_numerator, mean_size_denominator),
1459 keys_gen,
1460 values_gen,
1461 )
1462}
1463
1464/// Generates random [`HashMap`]s with a minimum size, with keys from one iterator and values from
1465/// another.
1466///
1467/// The sizes of the maps are sampled from a geometric distribution with a specified mean $m$, equal
1468/// to `mean_size_numerator / mean_size_denominator`. $m$ must be greater than `min_size`.
1469///
1470/// The key iterator must generate at least as many distinct elements as any size that is requested;
1471/// otherwise, this iterator will hang. The value iterator has no such requirement, since values may
1472/// repeat.
1473///
1474/// $$
1475/// P(\\{(k_i, v_i)\\}_ {i=0}^{n-1}) = n!P(n)\prod_ {i=0}^{n-1}P(k_i)P(v_i).
1476/// $$
1477///
1478/// The above formula assumes that the map is valid, \emph{i.e.} its keys are distinct. The $n!$
1479/// counts the orders in which the keys can be drawn; the values are drawn in the same order, so
1480/// each key order pairs with exactly one value order that produces the map.
1481///
1482/// `keys_gen` and `values_gen` must produce infinite iterators.
1483///
1484/// # Expected complexity per iteration
1485/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
1486///
1487/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
1488///
1489/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
1490/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
1491/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
1492/// and $m$ is the mean size.
1493///
1494/// # Panics
1495/// Panics if `mean_size_numerator` or `mean_size_denominator` are zero, if their ratio is less than
1496/// or equal to `min_size`, or if they are too large and manipulating them leads to arithmetic
1497/// overflow.
1498///
1499/// # Examples
1500/// ```
1501/// use itertools::Itertools;
1502/// use malachite_base::maps::random::random_hash_maps_min_size;
1503/// use malachite_base::num::random::{random_primitive_ints, random_unsigned_inclusive_range};
1504/// use malachite_base::random::EXAMPLE_SEED;
1505/// use maplit::hashmap;
1506///
1507/// let xs = random_hash_maps_min_size(
1508/// EXAMPLE_SEED,
1509/// 1,
1510/// &random_primitive_ints::<u8>,
1511/// &|seed| random_unsigned_inclusive_range::<u8>(seed, 0, 2),
1512/// 4,
1513/// 1,
1514/// );
1515/// let values = xs.take(10).collect_vec();
1516/// assert_eq!(
1517/// values,
1518/// &[
1519/// hashmap! {79 => 0},
1520/// hashmap! {10 => 0, 51 => 2, 80 => 1},
1521/// hashmap! {59 => 0, 85 => 0, 160 => 0, 245 => 0, 246 => 2, 253 => 0},
1522/// hashmap! {53 => 0},
1523/// hashmap! {214 => 1, 219 => 2},
1524/// hashmap! {120 => 1, 139 => 1, 233 => 2},
1525/// hashmap! {33 => 2, 157 => 1, 158 => 0, 161 => 0, 202 => 0, 236 => 1},
1526/// hashmap! {19 => 0, 72 => 2, 153 => 1, 155 => 0, 194 => 2},
1527/// hashmap! {25 => 1, 68 => 0, 74 => 0, 80 => 2, 97 => 1, 119 => 0, 236 => 1, 252 => 0},
1528/// hashmap! {33 => 1, 241 => 2}
1529/// ]
1530/// );
1531/// ```
1532#[inline]
1533pub fn random_hash_maps_min_size<I: Iterator, J: Iterator>(
1534 seed: Seed,
1535 min_size: u64,
1536 keys_gen: &dyn Fn(Seed) -> I,
1537 values_gen: &dyn Fn(Seed) -> J,
1538 mean_size_numerator: u64,
1539 mean_size_denominator: u64,
1540) -> RandomHashMaps<I::Item, J::Item, GeometricRandomNaturalValues<u64>, I, J>
1541where
1542 I::Item: Eq + Hash,
1543{
1544 random_hash_maps_from_size_iterator(
1545 seed,
1546 &|seed_2| {
1547 geometric_random_unsigned_inclusive_range(
1548 seed_2,
1549 min_size,
1550 u64::MAX,
1551 mean_size_numerator,
1552 mean_size_denominator,
1553 )
1554 },
1555 keys_gen,
1556 values_gen,
1557 )
1558}
1559
1560/// Generates random [`HashMap`]s with sizes in the half-open interval $[a, b)$, with keys from one
1561/// iterator and values from another.
1562///
1563/// The key iterator must generate at least as many distinct elements as any size that is requested;
1564/// otherwise, this iterator will hang. The value iterator has no such requirement, since values may
1565/// repeat.
1566///
1567/// $$
1568/// P(\\{(k_i, v_i)\\}_ {i=0}^{n-1}) = n!P(n)\prod_ {i=0}^{n-1}P(k_i)P(v_i).
1569/// $$
1570///
1571/// The above formula assumes that the map is valid, \emph{i.e.} its keys are distinct. The $n!$
1572/// counts the orders in which the keys can be drawn; the values are drawn in the same order, so
1573/// each key order pairs with exactly one value order that produces the map.
1574///
1575/// `keys_gen` and `values_gen` must produce infinite iterators.
1576///
1577/// # Expected complexity per iteration
1578/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
1579///
1580/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
1581///
1582/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
1583/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
1584/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
1585/// and $m$ is the mean size.
1586///
1587/// # Panics
1588/// Panics if $a \geq b$.
1589///
1590/// # Examples
1591/// ```
1592/// use itertools::Itertools;
1593/// use malachite_base::chars::random::random_char_inclusive_range;
1594/// use malachite_base::maps::random::random_hash_maps_size_range;
1595/// use malachite_base::num::random::random_unsigned_inclusive_range;
1596/// use malachite_base::random::EXAMPLE_SEED;
1597/// use maplit::hashmap;
1598///
1599/// let xs = random_hash_maps_size_range(
1600/// EXAMPLE_SEED,
1601/// 1,
1602/// 3,
1603/// &|seed| random_char_inclusive_range(seed, 'a', 'c'),
1604/// &|seed| random_unsigned_inclusive_range::<u8>(seed, 0, 1),
1605/// );
1606/// let values = xs.take(20).collect_vec();
1607/// assert_eq!(
1608/// values,
1609/// &[
1610/// hashmap! {'a' => 0},
1611/// hashmap! {'b' => 0},
1612/// hashmap! {'a' => 1, 'b' => 0},
1613/// hashmap! {'a' => 1, 'b' => 0},
1614/// hashmap! {'a' => 0, 'c' => 0},
1615/// hashmap! {'a' => 0, 'c' => 0},
1616/// hashmap! {'a' => 0},
1617/// hashmap! {'c' => 0},
1618/// hashmap! {'a' => 0, 'b' => 1},
1619/// hashmap! {'b' => 0, 'c' => 0},
1620/// hashmap! {'a' => 0},
1621/// hashmap! {'a' => 0, 'c' => 0},
1622/// hashmap! {'b' => 0, 'c' => 0},
1623/// hashmap! {'b' => 0},
1624/// hashmap! {'a' => 0, 'b' => 1},
1625/// hashmap! {'c' => 0},
1626/// hashmap! {'b' => 1, 'c' => 1},
1627/// hashmap! {'b' => 1, 'c' => 1},
1628/// hashmap! {'a' => 0},
1629/// hashmap! {'c' => 0}
1630/// ]
1631/// );
1632/// ```
1633#[inline]
1634pub fn random_hash_maps_size_range<I: Iterator, J: Iterator>(
1635 seed: Seed,
1636 a: u64,
1637 b: u64,
1638 keys_gen: &dyn Fn(Seed) -> I,
1639 values_gen: &dyn Fn(Seed) -> J,
1640) -> RandomHashMaps<I::Item, J::Item, RandomUnsignedRange<u64>, I, J>
1641where
1642 I::Item: Eq + Hash,
1643{
1644 random_hash_maps_from_size_iterator(
1645 seed,
1646 &|seed_2| random_unsigned_range(seed_2, a, b),
1647 keys_gen,
1648 values_gen,
1649 )
1650}
1651
1652/// Generates random [`HashMap`]s with sizes in the closed interval $[a, b]$, with keys from one
1653/// iterator and values from another.
1654///
1655/// The key iterator must generate at least as many distinct elements as any size that is requested;
1656/// otherwise, this iterator will hang. The value iterator has no such requirement, since values may
1657/// repeat.
1658///
1659/// $$
1660/// P(\\{(k_i, v_i)\\}_ {i=0}^{n-1}) = n!P(n)\prod_ {i=0}^{n-1}P(k_i)P(v_i).
1661/// $$
1662///
1663/// The above formula assumes that the map is valid, \emph{i.e.} its keys are distinct. The $n!$
1664/// counts the orders in which the keys can be drawn; the values are drawn in the same order, so
1665/// each key order pairs with exactly one value order that produces the map.
1666///
1667/// `keys_gen` and `values_gen` must produce infinite iterators.
1668///
1669/// # Expected complexity per iteration
1670/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
1671///
1672/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
1673///
1674/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
1675/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
1676/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
1677/// and $m$ is the mean size.
1678///
1679/// # Panics
1680/// Panics if $a > b$.
1681///
1682/// # Examples
1683/// ```
1684/// use itertools::Itertools;
1685/// use malachite_base::chars::random::random_char_inclusive_range;
1686/// use malachite_base::maps::random::random_hash_maps_size_inclusive_range;
1687/// use malachite_base::num::random::random_unsigned_inclusive_range;
1688/// use malachite_base::random::EXAMPLE_SEED;
1689/// use maplit::hashmap;
1690///
1691/// let xs = random_hash_maps_size_inclusive_range(
1692/// EXAMPLE_SEED,
1693/// 1,
1694/// 2,
1695/// &|seed| random_char_inclusive_range(seed, 'a', 'c'),
1696/// &|seed| random_unsigned_inclusive_range::<u8>(seed, 0, 1),
1697/// );
1698/// let values = xs.take(20).collect_vec();
1699/// assert_eq!(
1700/// values,
1701/// &[
1702/// hashmap! {'a' => 0},
1703/// hashmap! {'b' => 0},
1704/// hashmap! {'a' => 1, 'b' => 0},
1705/// hashmap! {'a' => 1, 'b' => 0},
1706/// hashmap! {'a' => 0, 'c' => 0},
1707/// hashmap! {'a' => 0, 'c' => 0},
1708/// hashmap! {'a' => 0},
1709/// hashmap! {'c' => 0},
1710/// hashmap! {'a' => 0, 'b' => 1},
1711/// hashmap! {'b' => 0, 'c' => 0},
1712/// hashmap! {'a' => 0},
1713/// hashmap! {'a' => 0, 'c' => 0},
1714/// hashmap! {'b' => 0, 'c' => 0},
1715/// hashmap! {'b' => 0},
1716/// hashmap! {'a' => 0, 'b' => 1},
1717/// hashmap! {'c' => 0},
1718/// hashmap! {'b' => 1, 'c' => 1},
1719/// hashmap! {'b' => 1, 'c' => 1},
1720/// hashmap! {'a' => 0},
1721/// hashmap! {'c' => 0}
1722/// ]
1723/// );
1724/// ```
1725#[inline]
1726pub fn random_hash_maps_size_inclusive_range<I: Iterator, J: Iterator>(
1727 seed: Seed,
1728 a: u64,
1729 b: u64,
1730 keys_gen: &dyn Fn(Seed) -> I,
1731 values_gen: &dyn Fn(Seed) -> J,
1732) -> RandomHashMaps<I::Item, J::Item, RandomUnsignedInclusiveRange<u64>, I, J>
1733where
1734 I::Item: Eq + Hash,
1735{
1736 random_hash_maps_from_size_iterator(
1737 seed,
1738 &|seed_2| random_unsigned_inclusive_range(seed_2, a, b),
1739 keys_gen,
1740 values_gen,
1741 )
1742}
1743/// Generates random [`HashMap`]s with a restricted number of distinct values.
1744#[derive(Clone, Debug)]
1745pub struct RandomHashMapsWithUniqueValueCount<
1746 K: Eq + Hash,
1747 V: Clone + Eq + Hash,
1748 I: Iterator<Item = u64>,
1749 J: Iterator<Item = K>,
1750 L: Iterator<Item = V>,
1751> {
1752 sizes: I,
1753 keys: J,
1754 values: L,
1755 range_generator: VariableRangeGenerator,
1756 a: u64,
1757 b: u64,
1758}
1759
1760impl<
1761 K: Eq + Hash,
1762 V: Clone + Eq + Hash,
1763 I: Iterator<Item = u64>,
1764 J: Iterator<Item = K>,
1765 L: Iterator<Item = V>,
1766> Iterator for RandomHashMapsWithUniqueValueCount<K, V, I, J, L>
1767{
1768 type Item = HashMap<K, V>;
1769
1770 fn next(&mut self) -> Option<HashMap<K, V>> {
1771 let size = self.sizes.next().unwrap();
1772 // A map with `size` entries has between 1 and `size` distinct values, or 0 if `size` is 0.
1773 // The size iterator is built so that this range always meets [`self.a`, `self.b`].
1774 let count = usize::exact_from(
1775 self.range_generator
1776 .next_in_inclusive_range::<u64>(max(self.a, min(size, 1)), min(self.b, size)),
1777 );
1778 let size = usize::exact_from(size);
1779 let mut vs = Vec::with_capacity(count);
1780 let mut seen = HashSet::with_capacity(count);
1781 while vs.len() < count {
1782 let value = self.values.next().unwrap();
1783 if seen.insert(value.clone()) {
1784 vs.push(value);
1785 }
1786 }
1787 // The first `count` keys drawn take the `count` distinct values, one each, so that every
1788 // one of them is used; the rest take a uniformly random one of them. The keys are drawn in
1789 // random order, so this does not favor any particular position in the map.
1790 let mut map = HashMap::new();
1791 let mut assigned = 0;
1792 while map.len() < size {
1793 let key = self.keys.next().unwrap();
1794 let range_generator = &mut self.range_generator;
1795 map.entry(key).or_insert_with(|| {
1796 let value = if assigned < count {
1797 vs[assigned].clone()
1798 } else {
1799 vs[range_generator.next_less_than::<usize>(count)].clone()
1800 };
1801 assigned += 1;
1802 value
1803 });
1804 }
1805 Some(map)
1806 }
1807}
1808
1809fn random_hash_maps_with_unique_value_count_from_size_iterator<
1810 K: Eq + Hash,
1811 V: Clone + Eq + Hash,
1812 I: Iterator<Item = u64>,
1813 J: Iterator<Item = K>,
1814 L: Iterator<Item = V>,
1815>(
1816 seed: Seed,
1817 sizes_gen: &dyn Fn(Seed) -> I,
1818 keys_gen: &dyn Fn(Seed) -> J,
1819 values_gen: &dyn Fn(Seed) -> L,
1820 a: u64,
1821 b: u64,
1822) -> RandomHashMapsWithUniqueValueCount<K, V, I, J, L> {
1823 RandomHashMapsWithUniqueValueCount {
1824 sizes: sizes_gen(seed.fork("sizes")),
1825 keys: keys_gen(seed.fork("keys")),
1826 values: values_gen(seed.fork("values")),
1827 range_generator: VariableRangeGenerator::new(seed.fork("unique_value_counts")),
1828 a,
1829 b,
1830 }
1831}
1832
1833/// Generates random [`HashMap`]s with a given number of distinct values, with keys from one
1834/// iterator and values from another.
1835///
1836/// The key iterator must generate at least as many distinct elements as any size that is requested,
1837/// and the value iterator at least as many distinct elements as any number of distinct values that
1838/// is requested; otherwise, this iterator will hang.
1839///
1840/// $$
1841/// P(m) = P(n)P(d)d!(n-d)!\frac{\prod_{j=0}^{d-1}c_j}{d^{n-d}}
1842/// \prod_{i=0}^{n-1}P(k_i)\prod_{j=0}^{d-1}P(w_j).
1843/// $$
1844///
1845/// Here the map $m$ has $n$ entries $(k_i, v_i)$ and $d$ distinct values $w_0, \ldots, w_{d-1}$,
1846/// the $j$th of which is the value of $c_j$ of the entries; $P(n)$ is the probability of drawing
1847/// the size $n$, and $P(d)$ that of drawing the distinct-value count $d$, which is uniform over the
1848/// counts that a size-$n$ map is allowed to have. The formula assumes that the map is valid,
1849/// \emph{i.e.} its keys are distinct and it has exactly $d$ distinct values. Maps with the same $n$
1850/// and $d$ are not equally likely: the $\prod_j c_j$ factor favors those whose values are spread
1851/// evenly over the keys.
1852///
1853/// `keys_gen` and `values_gen` must produce infinite iterators.
1854///
1855/// If `unique_value_count` is 0, the output consists of the empty map, repeated.
1856///
1857/// # Expected complexity per iteration
1858/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
1859///
1860/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
1861///
1862/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
1863/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
1864/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
1865/// and $m$ is the mean size.
1866///
1867/// # Panics
1868/// Panics if `mean_size_numerator` or `mean_size_denominator` are zero, if their ratio is less than
1869/// or equal to `unique_value_count`, or if they are too large and manipulating them leads to
1870/// arithmetic overflow.
1871///
1872/// # Examples
1873/// ```
1874/// use itertools::Itertools;
1875/// use malachite_base::maps::random::random_hash_maps_fixed_unique_value_count;
1876/// use malachite_base::num::random::{random_primitive_ints, random_unsigned_inclusive_range};
1877/// use malachite_base::random::EXAMPLE_SEED;
1878/// use maplit::hashmap;
1879///
1880/// let xs = random_hash_maps_fixed_unique_value_count(
1881/// EXAMPLE_SEED,
1882/// 1,
1883/// &random_primitive_ints::<u8>,
1884/// &|seed| random_unsigned_inclusive_range::<u8>(seed, 0, 2),
1885/// 2,
1886/// 1,
1887/// );
1888/// let values = xs.take(10).collect_vec();
1889/// assert_eq!(
1890/// values,
1891/// &[
1892/// hashmap! {79 => 0},
1893/// hashmap! {80 => 1},
1894/// hashmap! {10 => 2, 51 => 2, 59 => 2, 246 => 2, 253 => 2},
1895/// hashmap! {160 => 0},
1896/// hashmap! {53 => 0, 85 => 0, 245 => 0},
1897/// hashmap! {139 => 0, 214 => 0, 219 => 0},
1898/// hashmap! {120 => 2, 233 => 2},
1899/// hashmap! {33 => 0, 158 => 0, 236 => 0},
1900/// hashmap! {202 => 0},
1901/// hashmap! {157 => 0}
1902/// ]
1903/// );
1904/// ```
1905#[inline]
1906pub fn random_hash_maps_fixed_unique_value_count<I: Iterator, J: Iterator>(
1907 seed: Seed,
1908 unique_value_count: u64,
1909 keys_gen: &dyn Fn(Seed) -> I,
1910 values_gen: &dyn Fn(Seed) -> J,
1911 mean_size_numerator: u64,
1912 mean_size_denominator: u64,
1913) -> RandomHashMapsWithUniqueValueCount<I::Item, J::Item, GeometricRandomNaturalValues<u64>, I, J>
1914where
1915 I::Item: Eq + Hash,
1916 J::Item: Clone + Eq + Hash,
1917{
1918 random_hash_maps_unique_value_count_inclusive_range(
1919 seed,
1920 unique_value_count,
1921 unique_value_count,
1922 keys_gen,
1923 values_gen,
1924 mean_size_numerator,
1925 mean_size_denominator,
1926 )
1927}
1928
1929/// Generates random [`HashMap`]s whose number of distinct values is in the half-open interval $[a,
1930/// b)$, with keys from one iterator and values from another.
1931///
1932/// The key iterator must generate at least as many distinct elements as any size that is requested,
1933/// and the value iterator at least as many distinct elements as any number of distinct values that
1934/// is requested; otherwise, this iterator will hang.
1935///
1936/// $$
1937/// P(m) = P(n)P(d)d!(n-d)!\frac{\prod_{j=0}^{d-1}c_j}{d^{n-d}}
1938/// \prod_{i=0}^{n-1}P(k_i)\prod_{j=0}^{d-1}P(w_j).
1939/// $$
1940///
1941/// Here the map $m$ has $n$ entries $(k_i, v_i)$ and $d$ distinct values $w_0, \ldots, w_{d-1}$,
1942/// the $j$th of which is the value of $c_j$ of the entries; $P(n)$ is the probability of drawing
1943/// the size $n$, and $P(d)$ that of drawing the distinct-value count $d$, which is uniform over the
1944/// counts that a size-$n$ map is allowed to have. The formula assumes that the map is valid,
1945/// \emph{i.e.} its keys are distinct and it has exactly $d$ distinct values. Maps with the same $n$
1946/// and $d$ are not equally likely: the $\prod_j c_j$ factor favors those whose values are spread
1947/// evenly over the keys.
1948///
1949/// `keys_gen` and `values_gen` must produce infinite iterators.
1950///
1951/// # Expected complexity per iteration
1952/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
1953///
1954/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
1955///
1956/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
1957/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
1958/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
1959/// and $m$ is the mean size.
1960///
1961/// # Panics
1962/// Panics if $a \geq b$, if `mean_size_numerator` or `mean_size_denominator` are zero, if their
1963/// ratio is less than or equal to $a$, or if they are too large and manipulating them leads to
1964/// arithmetic overflow.
1965///
1966/// # Examples
1967/// ```
1968/// use itertools::Itertools;
1969/// use malachite_base::maps::random::random_hash_maps_unique_value_count_range;
1970/// use malachite_base::num::random::{random_primitive_ints, random_unsigned_inclusive_range};
1971/// use malachite_base::random::EXAMPLE_SEED;
1972/// use maplit::hashmap;
1973///
1974/// let xs = random_hash_maps_unique_value_count_range(
1975/// EXAMPLE_SEED,
1976/// 0,
1977/// 2,
1978/// &random_primitive_ints::<u8>,
1979/// &|seed| random_unsigned_inclusive_range::<u8>(seed, 0, 2),
1980/// 2,
1981/// 1,
1982/// );
1983/// let values = xs.take(10).collect_vec();
1984/// assert_eq!(
1985/// values,
1986/// &[
1987/// hashmap! {},
1988/// hashmap! {},
1989/// hashmap! {51 => 0, 79 => 0, 80 => 0},
1990/// hashmap! {},
1991/// hashmap! {10 => 1},
1992/// hashmap! {59 => 2},
1993/// hashmap! {160 => 0, 246 => 0, 253 => 0},
1994/// hashmap! {245 => 0},
1995/// hashmap! {53 => 0, 85 => 0, 139 => 0, 214 => 0, 219 => 0},
1996/// hashmap! {233 => 2}
1997/// ]
1998/// );
1999/// ```
2000#[inline]
2001pub fn random_hash_maps_unique_value_count_range<I: Iterator, J: Iterator>(
2002 seed: Seed,
2003 a: u64,
2004 b: u64,
2005 keys_gen: &dyn Fn(Seed) -> I,
2006 values_gen: &dyn Fn(Seed) -> J,
2007 mean_size_numerator: u64,
2008 mean_size_denominator: u64,
2009) -> RandomHashMapsWithUniqueValueCount<I::Item, J::Item, GeometricRandomNaturalValues<u64>, I, J>
2010where
2011 I::Item: Eq + Hash,
2012 J::Item: Clone + Eq + Hash,
2013{
2014 assert!(a < b, "a must be less than b. a: {a}, b: {b}");
2015 random_hash_maps_unique_value_count_inclusive_range(
2016 seed,
2017 a,
2018 b - 1,
2019 keys_gen,
2020 values_gen,
2021 mean_size_numerator,
2022 mean_size_denominator,
2023 )
2024}
2025
2026/// Generates random [`HashMap`]s whose number of distinct values is in the closed interval $[a,
2027/// b]$, with keys from one iterator and values from another.
2028///
2029/// The key iterator must generate at least as many distinct elements as any size that is requested,
2030/// and the value iterator at least as many distinct elements as any number of distinct values that
2031/// is requested; otherwise, this iterator will hang.
2032///
2033/// $$
2034/// P(m) = P(n)P(d)d!(n-d)!\frac{\prod_{j=0}^{d-1}c_j}{d^{n-d}}
2035/// \prod_{i=0}^{n-1}P(k_i)\prod_{j=0}^{d-1}P(w_j).
2036/// $$
2037///
2038/// Here the map $m$ has $n$ entries $(k_i, v_i)$ and $d$ distinct values $w_0, \ldots, w_{d-1}$,
2039/// the $j$th of which is the value of $c_j$ of the entries; $P(n)$ is the probability of drawing
2040/// the size $n$, and $P(d)$ that of drawing the distinct-value count $d$, which is uniform over the
2041/// counts that a size-$n$ map is allowed to have. The formula assumes that the map is valid,
2042/// \emph{i.e.} its keys are distinct and it has exactly $d$ distinct values. Maps with the same $n$
2043/// and $d$ are not equally likely: the $\prod_j c_j$ factor favors those whose values are spread
2044/// evenly over the keys.
2045///
2046/// `keys_gen` and `values_gen` must produce infinite iterators.
2047///
2048/// If $b$ is 0, the output consists of the empty map, repeated.
2049///
2050/// # Expected complexity per iteration
2051/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
2052///
2053/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
2054///
2055/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
2056/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
2057/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
2058/// and $m$ is the mean size.
2059///
2060/// # Panics
2061/// Panics if $a > b$, if `mean_size_numerator` or `mean_size_denominator` are zero, if their ratio
2062/// is less than or equal to $a$, or if they are too large and manipulating them leads to arithmetic
2063/// overflow.
2064///
2065/// # Examples
2066/// ```
2067/// use itertools::Itertools;
2068/// use malachite_base::maps::random::random_hash_maps_unique_value_count_inclusive_range;
2069/// use malachite_base::num::random::{random_primitive_ints, random_unsigned_inclusive_range};
2070/// use malachite_base::random::EXAMPLE_SEED;
2071/// use maplit::hashmap;
2072///
2073/// let xs = random_hash_maps_unique_value_count_inclusive_range(
2074/// EXAMPLE_SEED,
2075/// 0,
2076/// 1,
2077/// &random_primitive_ints::<u8>,
2078/// &|seed| random_unsigned_inclusive_range::<u8>(seed, 0, 2),
2079/// 2,
2080/// 1,
2081/// );
2082/// let values = xs.take(10).collect_vec();
2083/// assert_eq!(
2084/// values,
2085/// &[
2086/// hashmap! {},
2087/// hashmap! {},
2088/// hashmap! {51 => 0, 79 => 0, 80 => 0},
2089/// hashmap! {},
2090/// hashmap! {10 => 1},
2091/// hashmap! {59 => 2},
2092/// hashmap! {160 => 0, 246 => 0, 253 => 0},
2093/// hashmap! {245 => 0},
2094/// hashmap! {53 => 0, 85 => 0, 139 => 0, 214 => 0, 219 => 0},
2095/// hashmap! {233 => 2}
2096/// ]
2097/// );
2098/// ```
2099pub fn random_hash_maps_unique_value_count_inclusive_range<I: Iterator, J: Iterator>(
2100 seed: Seed,
2101 a: u64,
2102 b: u64,
2103 keys_gen: &dyn Fn(Seed) -> I,
2104 values_gen: &dyn Fn(Seed) -> J,
2105 mean_size_numerator: u64,
2106 mean_size_denominator: u64,
2107) -> RandomHashMapsWithUniqueValueCount<I::Item, J::Item, GeometricRandomNaturalValues<u64>, I, J>
2108where
2109 I::Item: Eq + Hash,
2110 J::Item: Clone + Eq + Hash,
2111{
2112 let (size_a, size_b) = compatible_size_range(0, u64::MAX, a, b);
2113 random_hash_maps_with_unique_value_count_from_size_iterator(
2114 seed,
2115 &|seed_2| {
2116 geometric_random_unsigned_inclusive_range(
2117 seed_2,
2118 size_a,
2119 size_b,
2120 mean_size_numerator,
2121 mean_size_denominator,
2122 )
2123 },
2124 keys_gen,
2125 values_gen,
2126 a,
2127 b,
2128 )
2129}
2130
2131/// Generates random [`HashMap`]s whose size is in the closed interval $[\text{size\_a},
2132/// \text{size\_b}]$ and whose number of distinct values is in the closed interval
2133/// $[\text{unique\_value\_count\_a}, \text{unique\_value\_count\_b}]$, with keys from one iterator
2134/// and values from another.
2135///
2136/// A map with $k$ entries has between 1 and $k$ distinct values, or 0 if $k$ is 0, so the sizes are
2137/// drawn uniformly not from all of $[\text{size\_a}, \text{size\_b}]$ but from those of its members
2138/// that can have an allowed number of distinct values.
2139///
2140/// The key iterator must generate at least as many distinct elements as any size that is requested,
2141/// and the value iterator at least as many distinct elements as any number of distinct values that
2142/// is requested; otherwise, this iterator will hang.
2143///
2144/// $$
2145/// P(m) = P(n)P(d)d!(n-d)!\frac{\prod_{j=0}^{d-1}c_j}{d^{n-d}}
2146/// \prod_{i=0}^{n-1}P(k_i)\prod_{j=0}^{d-1}P(w_j).
2147/// $$
2148///
2149/// Here the map $m$ has $n$ entries $(k_i, v_i)$ and $d$ distinct values $w_0, \ldots, w_{d-1}$,
2150/// the $j$th of which is the value of $c_j$ of the entries; $P(n)$ is the probability of drawing
2151/// the size $n$, and $P(d)$ that of drawing the distinct-value count $d$, which is uniform over the
2152/// counts that a size-$n$ map is allowed to have. The formula assumes that the map is valid,
2153/// \emph{i.e.} its keys are distinct and it has exactly $d$ distinct values. Maps with the same $n$
2154/// and $d$ are not equally likely: the $\prod_j c_j$ factor favors those whose values are spread
2155/// evenly over the keys.
2156///
2157/// `keys_gen` and `values_gen` must produce infinite iterators.
2158///
2159/// # Expected complexity per iteration
2160/// $T(i) = O(m (T^\prime(i) + T^{\prime\prime}(i)))$
2161///
2162/// $M(i) = O(m (M^\prime(i) + M^{\prime\prime}(i)))$
2163///
2164/// where $T$ is time, $M$ is additional memory, $i$ is the iteration number, $T^\prime$ and
2165/// $M^\prime$ are the time and memory functions of the iterators produced by `keys_gen`,
2166/// $T^{\prime\prime}$ and $M^{\prime\prime}$ are those of the iterators produced by `values_gen`,
2167/// and $m$ is the mean size.
2168///
2169/// # Panics
2170/// Panics if $\text{size\_a} > \text{size\_b}$, if $\text{unique\_value\_count\_a} >
2171/// \text{unique\_value\_count\_b}$, or if no size in $[\text{size\_a}, \text{size\_b}]$ can have a
2172/// number of distinct values in $[\text{unique\_value\_count\_a}, \text{unique\_value\_count\_b}]$.
2173///
2174/// # Examples
2175/// ```
2176/// use itertools::Itertools;
2177/// use malachite_base::chars::random::random_char_inclusive_range;
2178/// use malachite_base::maps::random::random_hash_maps_size_and_unique_value_count_inclusive_range;
2179/// use malachite_base::num::random::random_unsigned_inclusive_range;
2180/// use malachite_base::random::EXAMPLE_SEED;
2181/// use maplit::hashmap;
2182///
2183/// let xs = random_hash_maps_size_and_unique_value_count_inclusive_range(
2184/// EXAMPLE_SEED,
2185/// 2,
2186/// 3,
2187/// 1,
2188/// 2,
2189/// &|seed| random_char_inclusive_range(seed, 'a', 'c'),
2190/// &|seed| random_unsigned_inclusive_range::<u8>(seed, 0, 2),
2191/// );
2192/// let values = xs.take(20).collect_vec();
2193/// assert_eq!(
2194/// values,
2195/// &[
2196/// hashmap! {'a' => 0, 'b' => 1},
2197/// hashmap! {'a' => 2, 'b' => 2},
2198/// hashmap! {'a' => 0, 'b' => 0, 'c' => 0},
2199/// hashmap! {'a' => 2, 'b' => 2, 'c' => 0},
2200/// hashmap! {'a' => 0, 'b' => 0, 'c' => 0},
2201/// hashmap! {'a' => 0, 'b' => 0, 'c' => 0},
2202/// hashmap! {'a' => 0, 'b' => 0},
2203/// hashmap! {'b' => 0, 'c' => 0},
2204/// hashmap! {'a' => 1, 'b' => 1, 'c' => 2},
2205/// hashmap! {'a' => 1, 'b' => 2, 'c' => 1},
2206/// hashmap! {'b' => 2, 'c' => 1},
2207/// hashmap! {'a' => 1, 'b' => 0, 'c' => 1},
2208/// hashmap! {'a' => 0, 'b' => 0, 'c' => 1},
2209/// hashmap! {'a' => 2, 'c' => 0},
2210/// hashmap! {'a' => 0, 'b' => 0, 'c' => 0},
2211/// hashmap! {'b' => 0, 'c' => 2},
2212/// hashmap! {'a' => 1, 'b' => 1, 'c' => 1},
2213/// hashmap! {'a' => 1, 'b' => 1, 'c' => 1},
2214/// hashmap! {'b' => 0, 'c' => 2},
2215/// hashmap! {'a' => 1, 'c' => 1}
2216/// ]
2217/// );
2218/// ```
2219pub fn random_hash_maps_size_and_unique_value_count_inclusive_range<I: Iterator, J: Iterator>(
2220 seed: Seed,
2221 size_a: u64,
2222 size_b: u64,
2223 unique_value_count_a: u64,
2224 unique_value_count_b: u64,
2225 keys_gen: &dyn Fn(Seed) -> I,
2226 values_gen: &dyn Fn(Seed) -> J,
2227) -> RandomHashMapsWithUniqueValueCount<I::Item, J::Item, RandomUnsignedInclusiveRange<u64>, I, J>
2228where
2229 I::Item: Eq + Hash,
2230 J::Item: Clone + Eq + Hash,
2231{
2232 let (lo, hi) =
2233 compatible_size_range(size_a, size_b, unique_value_count_a, unique_value_count_b);
2234 random_hash_maps_with_unique_value_count_from_size_iterator(
2235 seed,
2236 &|seed_2| random_unsigned_inclusive_range(seed_2, lo, hi),
2237 keys_gen,
2238 values_gen,
2239 unique_value_count_a,
2240 unique_value_count_b,
2241 )
2242}