1use super::StalinFind;
2
3use std::cmp;
4
5impl<T: PartialOrd> StalinFind<T> for Vec<T> {
6 #[inline]
7 fn len(&self) -> usize {
8 self.len()
9 }
10
11 #[inline]
12 fn is_empty(&self) -> bool {
13 self.is_empty()
14 }
15
16 fn stalin(&mut self, i: T, l: usize, r: usize) -> Option<usize>
17 where T: cmp::PartialEq + cmp::PartialOrd {
18 let m = (l + r) / 2;
19 if self[m] == i {
20 Some(m)
21 } else {
22 self.remove(m);
23 if m == 0 || l > r {
24 if self.is_empty() {
25 None
26 } else {
27 self.stalin(i, 0, self.len() - 1)
28 }
29 } else if self[m - 1] < i {
30 self.stalin(i, m, r - 1)
31 } else {
32 self.stalin(i, l, m - 1)
33 }
34 }
35 }
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41 use rand::Rng;
42
43 #[test]
44 fn randomised_test() {
45 let n = 100; let mut rng = rand::thread_rng();
48 let sought = rng.gen_range(0..n);
49 let amount = rng.gen_range(0..n);
50 let range = rand::distributions::uniform::Uniform::new(0, n);
51 let mut vector: Vec<u64> = (0..amount).map(|_| rng.sample(&range)).collect();
52
53 let i = vector.iter().position(|x| x == &sought);
55 if i.is_some() {
56 if let Some(find) = vector.stalin_find(sought) {
57 assert_eq!(vector[find], sought)
58 }
59 } else {
60 let find = vector.stalin_find(sought);
61 assert_eq!(find, None)
62 }
63 }
64
65 #[test]
66 fn find_on_sorted() {
67 let mut sorted = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
68 let find = sorted.stalin_find(3);
69 assert!(find.is_some());
70 assert_eq!(
71 find,
72 Some(1),
73 );
74 assert_eq!(
75 sorted,
76 vec![1, 3, 4, 6, 7, 8, 9],
77 );
78 if let Some(find_3) = find {
79 assert_eq!(
80 3, sorted[find_3]
81 );
82 }
83 }
84
85 #[test]
86 fn find_on_unsorted() {
87 let mut unsorted = vec![33, 55, 3, 4, 7657, 6, 7, 8];
88 assert_eq!(
89 unsorted.stalin_find(3),
90 Some(0),
91 );
92 assert_eq!(
93 unsorted,
94 vec![3, 7657, 7, 8],
95 );
96 if let Some(find_7) = unsorted.stalin_find(7) {
97 assert_eq!(
98 7, unsorted[find_7]
99 );
100 }
101 }
102
103 #[test]
104 fn find_fail() {
105 let mut unsorted = vec![33, 55, 3, 4, 7657, 6, 7, 8];
106 assert_eq!(
107 unsorted.stalin_find(77),
108 None,
109 );
110 assert_eq!(
111 unsorted,
112 vec![],
113 );
114 }
115
116 #[test]
117 fn find_not_fail() {
118 let mut unsorted = vec![33, 55, 3, 4, 7657, 6, 7, 8, 2];
119 assert_eq!(
120 unsorted.stalin_find(2),
121 Some(0),
122 );
123 assert_eq!(
124 unsorted,
125 vec![2],
126 );
127 }
128
129 #[test]
130 fn find_not_fingon() {
131 let mut unsorted = vec![12, 11, 4, 5, 7, 8, 2];
132 assert_eq!(
133 unsorted.stalin_find(9),
134 None,
135 );
136 assert_eq!(
137 unsorted,
138 vec![],
139 );
140 }
141
142 #[test]
143 fn find_not_fingon2() {
144 let mut unsorted = vec![33, 55, 3, 4, 7657, 6, 33, 7, 8, 2];
145 assert_eq!(
146 unsorted.stalin_find(9),
147 None,
148 );
149 assert_eq!(
150 unsorted,
151 vec![],
152 );
153 }
154}