|
1 |
| -use super::traits::MutableSorter; |
2 | 1 | use crate::math::PCG32;
|
| 2 | +use crate::sorting::traits::Sorter; |
3 | 3 | use std::time::{SystemTime, UNIX_EPOCH};
|
4 | 4 |
|
5 |
| -const DEFAULT: u64 = 4294967296; |
| 5 | +const DEFAULT: u64 = 2 << 31; // 2^32 |
6 | 6 |
|
7 |
| -pub struct BogoSort; |
| 7 | +fn is_sorted<T: Ord>(arr: &[T], len: usize) -> bool { |
| 8 | + if len <= 1 { |
| 9 | + return true; |
| 10 | + } |
8 | 11 |
|
9 |
| -impl BogoSort { |
10 |
| - fn is_sorted<T: Ord>(arr: &[T], len: usize) -> bool { |
11 |
| - for i in 0..len - 1 { |
12 |
| - if arr[i] > arr[i + 1] { |
13 |
| - return false; |
14 |
| - } |
| 12 | + for i in 0..len - 1 { |
| 13 | + if arr[i] > arr[i + 1] { |
| 14 | + return false; |
15 | 15 | }
|
16 |
| - |
17 |
| - true |
18 |
| - } |
19 |
| - #[cfg(target_pointer_width = "64")] |
20 |
| - fn generate_index(range: usize, generator: &mut PCG32) -> usize { |
21 |
| - generator.get_u64() as usize % range |
22 | 16 | }
|
23 | 17 |
|
24 |
| - #[cfg(not(target_pointer_width = "64"))] |
25 |
| - fn generate_index(range: usize, generator: &mut PCG32) -> usize { |
26 |
| - generator.get_u32() as usize % range |
| 18 | + true |
| 19 | +} |
| 20 | +#[cfg(target_pointer_width = "64")] |
| 21 | +fn generate_index(range: usize, generator: &mut PCG32) -> usize { |
| 22 | + generator.get_u64() as usize % range |
| 23 | +} |
| 24 | + |
| 25 | +#[cfg(not(target_pointer_width = "64"))] |
| 26 | +fn generate_index(range: usize, generator: &mut PCG32) -> usize { |
| 27 | + generator.get_u32() as usize % range |
| 28 | +} |
| 29 | + |
| 30 | +/** |
| 31 | + * Fisher–Yates shuffle for generating random permutation. |
| 32 | + */ |
| 33 | +fn permute_randomly<T>(arr: &mut [T], len: usize, generator: &mut PCG32) { |
| 34 | + if len <= 1 { |
| 35 | + return; |
27 | 36 | }
|
28 | 37 |
|
29 |
| - /** |
30 |
| - * Fisher–Yates shuffle for generating random permutation. |
31 |
| - */ |
32 |
| - fn permute_randomly<T>(arr: &mut [T], len: usize, generator: &mut PCG32) { |
33 |
| - for i in (1..len).rev() { |
34 |
| - let j = BogoSort::generate_index(i + 1, generator); |
35 |
| - arr.swap(i, j); |
36 |
| - } |
| 38 | + for i in (1..len).rev() { |
| 39 | + let j = generate_index(i + 1, generator); |
| 40 | + arr.swap(i, j); |
37 | 41 | }
|
38 | 42 | }
|
39 | 43 |
|
40 |
| -impl<T> MutableSorter<T> for BogoSort { |
41 |
| - fn sort(arr: &mut [T]) |
42 |
| - where |
43 |
| - T: Ord, |
44 |
| - { |
45 |
| - let seed = match SystemTime::now().duration_since(UNIX_EPOCH) { |
46 |
| - Ok(duration) => duration.as_millis() as u64, |
47 |
| - Err(_) => DEFAULT, |
48 |
| - }; |
| 44 | +fn bogo_sort<T: Ord>(arr: &mut [T]) { |
| 45 | + let seed = match SystemTime::now().duration_since(UNIX_EPOCH) { |
| 46 | + Ok(duration) => duration.as_millis() as u64, |
| 47 | + Err(_) => DEFAULT, |
| 48 | + }; |
49 | 49 |
|
50 |
| - let mut random_generator = PCG32::new_default(seed); |
| 50 | + let mut random_generator = PCG32::new_default(seed); |
51 | 51 |
|
52 |
| - let arr_length = arr.len(); |
53 |
| - while !BogoSort::is_sorted(arr, arr_length) { |
54 |
| - BogoSort::permute_randomly(arr, arr_length, &mut random_generator); |
55 |
| - } |
| 52 | + let arr_length = arr.len(); |
| 53 | + while !is_sorted(arr, arr_length) { |
| 54 | + permute_randomly(arr, arr_length, &mut random_generator); |
| 55 | + } |
| 56 | +} |
| 57 | + |
| 58 | +pub struct BogoSort; |
| 59 | + |
| 60 | +impl<T> Sorter<T> for BogoSort |
| 61 | +where |
| 62 | + T: Ord + Copy, |
| 63 | +{ |
| 64 | + fn sort_inplace(arr: &mut [T]) { |
| 65 | + bogo_sort(arr); |
56 | 66 | }
|
57 | 67 | }
|
58 | 68 |
|
59 | 69 | #[cfg(test)]
|
60 | 70 | mod tests {
|
61 |
| - use super::super::traits::MutableSorter; |
62 |
| - use super::BogoSort; |
| 71 | + use crate::sorting::traits::Sorter; |
| 72 | + use crate::sorting::BogoSort; |
63 | 73 |
|
64 |
| - sorting_tests!(BogoSort::sort, inplace); |
| 74 | + sorting_tests!(BogoSort::sort, bogo_sort); |
| 75 | + sorting_tests!(BogoSort::sort_inplace, bogo_sort, inplace); |
65 | 76 | }
|
0 commit comments