sorting_race/services/
generator.rs1use crate::models::config::Distribution;
4use rand::{Rng, SeedableRng};
5use rand::rngs::StdRng;
6
7#[derive(Debug)]
9pub struct ArrayGenerator {
10 seed: u64,
11}
12
13impl ArrayGenerator {
14 pub fn new(seed: u64) -> Self {
16 Self { seed }
17 }
18
19 pub fn generate(&self, size: usize, distribution: &Distribution) -> Vec<i32> {
21 if size == 0 {
22 return Vec::new();
23 }
24
25 match distribution {
26 Distribution::Shuffled => self.generate_shuffled(size),
27 Distribution::NearlySorted => self.generate_nearly_sorted(size),
28 Distribution::Reversed => self.generate_reversed(size),
29 Distribution::FewUnique => self.generate_few_unique(size),
30 Distribution::Sorted => self.generate_sorted(size),
31 Distribution::WithDuplicates => self.generate_with_duplicates(size),
32 }
33 }
34
35 fn generate_shuffled(&self, size: usize) -> Vec<i32> {
37 let mut rng = StdRng::seed_from_u64(self.seed);
38 let mut array: Vec<i32> = (1..=size as i32).collect();
39
40 for i in (1..size).rev() {
42 let j = rng.random_range(0..=i);
43 array.swap(i, j);
44 }
45
46 array
47 }
48
49 fn generate_nearly_sorted(&self, size: usize) -> Vec<i32> {
51 let mut rng = StdRng::seed_from_u64(self.seed);
52 let mut array: Vec<i32> = (1..=size as i32).collect();
53
54 let swaps = (size / 10).max(1);
56 for _ in 0..swaps {
57 let i = rng.random_range(0..size);
58 let j = rng.random_range(0..size);
59 array.swap(i, j);
60 }
61
62 array
63 }
64
65 fn generate_reversed(&self, size: usize) -> Vec<i32> {
67 (1..=size as i32).rev().collect()
68 }
69
70 fn generate_few_unique(&self, size: usize) -> Vec<i32> {
72 let mut rng = StdRng::seed_from_u64(self.seed);
73 let unique_count = (size / 10).max(3).min(size); let values: Vec<i32> = (1..=unique_count as i32).collect();
75
76 let mut array = Vec::with_capacity(size);
77 for _ in 0..size {
78 let idx = rng.random_range(0..values.len());
79 array.push(values[idx]);
80 }
81
82 array
83 }
84
85 fn generate_sorted(&self, size: usize) -> Vec<i32> {
87 (1..=size as i32).collect()
88 }
89
90 fn generate_with_duplicates(&self, size: usize) -> Vec<i32> {
92 let mut rng = StdRng::seed_from_u64(self.seed);
93 let mut array = Vec::with_capacity(size);
94
95 for i in 0..size {
97 if i < size / 2 {
98 array.push((i + 1) as i32);
100 } else {
101 let idx = rng.random_range(0..size / 2);
103 array.push((idx + 1) as i32);
104 }
105 }
106
107 for i in (1..size).rev() {
109 let j = rng.random_range(0..=i);
110 array.swap(i, j);
111 }
112
113 array
114 }
115
116 pub fn validate_array(array: &[i32], size: usize, distribution: &Distribution) -> bool {
118 if array.len() != size {
119 return false;
120 }
121
122 if size == 0 {
123 return true;
124 }
125
126 match distribution {
127 Distribution::Sorted => {
128 array.windows(2).all(|w| w[0] <= w[1])
130 }
131 Distribution::Reversed => {
132 array.windows(2).all(|w| w[0] >= w[1])
134 }
135 _ => {
136 array.iter().all(|&x| x > 0 && x <= size as i32 * 2)
138 }
139 }
140 }
141}
142
143#[cfg(test)]
144mod tests {
145 use super::*;
146
147 #[test]
148 fn test_deterministic_generation() {
149 let gen1 = ArrayGenerator::new(42);
150 let gen2 = ArrayGenerator::new(42);
151
152 let array1 = gen1.generate(10, &Distribution::Shuffled);
153 let array2 = gen2.generate(10, &Distribution::Shuffled);
154
155 assert_eq!(array1, array2);
156 }
157
158 #[test]
159 fn test_different_seeds() {
160 let gen1 = ArrayGenerator::new(42);
161 let gen2 = ArrayGenerator::new(43);
162
163 let array1 = gen1.generate(10, &Distribution::Shuffled);
164 let array2 = gen2.generate(10, &Distribution::Shuffled);
165
166 assert_ne!(array1, array2);
167 }
168
169 #[test]
170 fn test_sorted_distribution() {
171 let generator = ArrayGenerator::new(42);
172 let array = generator.generate(10, &Distribution::Sorted);
173
174 assert_eq!(array, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
175 }
176
177 #[test]
178 fn test_reversed_distribution() {
179 let generator = ArrayGenerator::new(42);
180 let array = generator.generate(10, &Distribution::Reversed);
181
182 assert_eq!(array, vec![10, 9, 8, 7, 6, 5, 4, 3, 2, 1]);
183 }
184
185 #[test]
186 fn test_empty_array() {
187 let generator = ArrayGenerator::new(42);
188 let array = generator.generate(0, &Distribution::Shuffled);
189
190 assert!(array.is_empty());
191 }
192
193 #[test]
194 fn test_array_validation() {
195 let generator = ArrayGenerator::new(42);
196
197 let sorted = generator.generate(5, &Distribution::Sorted);
198 assert!(ArrayGenerator::validate_array(&sorted, 5, &Distribution::Sorted));
199
200 let reversed = generator.generate(5, &Distribution::Reversed);
201 assert!(ArrayGenerator::validate_array(&reversed, 5, &Distribution::Reversed));
202
203 let shuffled = generator.generate(5, &Distribution::Shuffled);
204 assert!(ArrayGenerator::validate_array(&shuffled, 5, &Distribution::Shuffled));
205 }
206}