sort_it/algorithms/
bogosort.rs

1use std::time::{ Instant, Duration };
2use rand::prelude::*;
3use super::IsSorted;
4
5/// A trait providing the bogosort method.
6pub trait Bogosort<T: PartialEq + PartialOrd + Clone + Copy> {
7    /// The bogosort algorithm.
8    ///
9    /// Sorts the `Vec` it is called on -- or dies trying.
10    fn bogosort(&mut self);
11
12    /// The bogosort algorithm but timed.
13    ///
14    /// Sorts the `Vec` it is called on and returns the `Duration` of the process -- or dies trying.
15    fn bogosort_timed(&mut self) -> Duration;
16
17    /// The bogosort algorithm but stepped.
18    ///
19    /// Sorts the `Vec` it is called on and returns a `Vec` containing each step of the process 
20    /// -- or dies trying.
21    fn bogosort_stepped(&mut self) -> Vec<Vec<T>>;
22
23    /// The bogosort algorithm but stepped _and_ timed.
24    ///
25    /// Sorts the `Vec` it is called on and returns a `Vec` containing each step of the process,
26    /// including the `Duration` of the entire process -- or dies trying.
27    fn bogosort_stepped_and_timed(&mut self) -> (Vec<Vec<T>>, Duration);
28}
29
30/// The trait implementation of the bogosort algorithm.
31impl<T> Bogosort<T> for Vec<T> 
32    where T: PartialEq + PartialOrd + Clone + Copy,
33{
34    fn bogosort(&mut self) {
35        if self.len() <= 1 {
36            return;
37        }
38
39        let mut rng = rand::thread_rng();
40        while !self.is_sorted() {
41            self.shuffle(&mut rng);
42        }
43    }
44
45    fn bogosort_timed(&mut self) -> Duration {
46        let time = Instant::now();
47
48        if self.len() <= 1 {
49            return time.elapsed();
50        }
51
52        let mut rng = rand::thread_rng();
53        while !self.is_sorted() {
54            self.shuffle(&mut rng);
55        }
56
57        return time.elapsed();
58    }
59
60    fn bogosort_stepped(&mut self) -> Vec<Vec<T>> {
61        let mut steps = vec![self.clone()];
62
63        if self.len() <= 1 {
64            return steps;
65        }
66
67        let mut rng = rand::thread_rng();
68        while !self.is_sorted() {
69            self.shuffle(&mut rng);
70            steps.push(self.clone());
71        }
72
73        return steps;
74    }
75
76    fn bogosort_stepped_and_timed(&mut self) -> (Vec<Vec<T>>, Duration) {
77        let time = Instant::now();
78
79        let mut steps = vec![self.clone()];
80
81        if self.len() <= 1 {
82            return (steps, time.elapsed());
83        }
84
85        let mut rng = rand::thread_rng();
86        while !self.is_sorted() {
87            self.shuffle(&mut rng);
88            steps.push(self.clone());
89        }
90
91        (steps, time.elapsed())
92    }
93}
94
95/// The bogosort algorithm.
96///
97/// Sorts the given `Vec` and returns the result -- or dies trying.
98pub fn bogosort<T>(mut arr: Vec<T>) -> Vec<T> 
99    where T: PartialEq + PartialOrd + Clone + Copy,
100{
101    if arr.len() <= 1 {
102        return arr;
103    }
104
105    let mut rng = rand::thread_rng();
106    while !arr.is_sorted() {
107        arr.shuffle(&mut rng);
108    }
109
110    return arr;
111}
112
113/// The bogosort algorithm but timed.
114///
115/// Sorts the given `Vec` and returns the result and the `Duration` of the process -- or dies trying.
116pub fn bogosort_timed<T>(mut arr: Vec<T>) -> (Vec<T>, Duration)
117    where T: PartialEq + PartialOrd + Clone + Copy,
118{
119    let time = Instant::now();
120
121    if arr.len() <= 1 {
122        return (arr, time.elapsed());
123    }
124
125    let mut rng = rand::thread_rng();
126    while !arr.is_sorted() {
127        arr.shuffle(&mut rng);
128    }
129
130    (arr, time.elapsed())
131}
132
133/// The bogosort algorithm but stepped.
134///
135/// Sorts the given `Vec` and returns the result and a `Vec` containing the steps of the process --
136/// or dies trying.
137pub fn bogosort_stepped<T>(mut arr: Vec<T>) -> (Vec<T>, Vec<Vec<T>>) 
138    where T: PartialEq + PartialOrd + Clone + Copy,
139{
140    let mut steps = vec![arr.clone()];
141
142    if arr.len() <= 1 {
143        return (arr, steps);
144    }
145
146    let mut rng = rand::thread_rng();
147    while !arr.is_sorted() {
148        arr.shuffle(&mut rng);
149        steps.push(arr.clone());
150    }
151
152    (arr, steps)
153}
154
155/// The bogosort algorithm but stepped _and_ timed.
156///
157/// Sorts the given `Vec` and returns the result and a `Vec` containing the steps of the process,
158/// including the `Duration` of the entire process -- or dies trying.
159pub fn bogosort_stepped_and_timed<T>(mut arr: Vec<T>) -> (Vec<T>, Vec<Vec<T>>, Duration)
160    where T: PartialEq + PartialOrd + Clone + Copy,
161{
162    let time = Instant::now();
163
164    let mut steps = vec![arr.clone()];
165
166    if arr.len() <= 1 {
167        return (arr, steps, time.elapsed());
168    }
169
170    let mut rng = rand::thread_rng();
171    while !arr.is_sorted() {
172        arr.shuffle(&mut rng);
173        steps.push(arr.clone());
174    }
175
176    (arr, steps, time.elapsed())
177}