1use crate::cfg_feature_alloc;
10cfg_feature_alloc! {
11 extern crate alloc;
12}
13#[macro_export]
14macro_rules! array {
15 (@accum (0, $($_es:expr),*) -> ($($body:tt)*))
16 => {array!(@as_expr [$($body)*])};
17 (@accum (1, $($es:expr),*) -> ($($body:tt)*))
18 => {array!(@accum (0, $($es),*) -> ($($body)* $($es,)*))};
19 (@accum (2, $($es:expr),*) -> ($($body:tt)*))
20 => {array!(@accum (0, $($es),*) -> ($($body)* $($es,)* $($es,)*))};
21 (@accum (3, $($es:expr),*) -> ($($body:tt)*))
22 => {array!(@accum (2, $($es),*) -> ($($body)* $($es,)*))};
23 (@accum (4, $($es:expr),*) -> ($($body:tt)*))
24 => {array!(@accum (2, $($es,)* $($es),*) -> ($($body)*))};
25 (@accum (5, $($es:expr),*) -> ($($body:tt)*))
26 => {array!(@accum (4, $($es),*) -> ($($body)* $($es,)*))};
27 (@accum (6, $($es:expr),*) -> ($($body:tt)*))
28 => {array!(@accum (4, $($es),*) -> ($($body)* $($es,)* $($es,)*))};
29 (@accum (7, $($es:expr),*) -> ($($body:tt)*))
30 => {array!(@accum (4, $($es),*) -> ($($body)* $($es,)* $($es,)* $($es,)*))};
31 (@accum (8, $($es:expr),*) -> ($($body:tt)*))
32 => {array!(@accum (4, $($es,)* $($es),*) -> ($($body)*))};
33 (@accum (16, $($es:expr),*) -> ($($body:tt)*))
34 => {array!(@accum (8, $($es,)* $($es),*) -> ($($body)*))};
35 (@accum (32, $($es:expr),*) -> ($($body:tt)*))
36 => {array!(@accum (16, $($es,)* $($es),*) -> ($($body)*))};
37 (@accum (64, $($es:expr),*) -> ($($body:tt)*))
38 => {array!(@accum (32, $($es,)* $($es),*) -> ($($body)*))};
39
40 (@as_expr $e:expr) => {$e};
41
42 [$e:expr; $n:tt] => { array!(@accum ($n, $e) -> ()) };
43}
44
45pub fn max_index<T: PartialOrd>(arr: &[T]) -> Option<usize> {
58 let mut max_idx: Option<usize> = None;
59 let mut max_val: Option<&T> = None;
60 for (idx, val) in arr.iter().enumerate() {
61 if max_idx.is_none() {
62 max_idx = Some(idx);
63 max_val = Some(val);
64 } else if let Some(mv) = max_val {
65 if val.gt(mv) {
66 max_val = Some(val);
67 max_idx = Some(idx);
68 }
69 }
70 }
71 max_idx
72}
73
74pub fn copy_subset<T: Copy + Default, const N: usize>(arr: &[T]) -> [T; N] {
78 let mut out = [T::default(); N];
79 out.copy_from_slice(arr.split_at(N).0);
80 out
81}
82
83pub trait SliceTools<T> {
84 fn copy_subset<const N: usize>(&self) -> [T; N]
88 where
89 T: Copy + Default;
90 fn limit(&self, limit: usize) -> &[T];
91 cfg_feature_alloc! {
92 fn reversed(&self) -> alloc::boxed::Box<[T]> where T: Copy+Default;
93 }
94}
95impl<T> SliceTools<T> for [T]
96where
97 T: Copy + Default,
98{
99 fn copy_subset<const N: usize>(&self) -> [T; N]
100 where
101 T: Copy + Default,
102 {
103 copy_subset(self)
104 }
105
106 fn limit(&self, limit: usize) -> &[T] {
107 if limit < self.len() {
108 self.split_at(limit).0
109 } else {
110 self
111 }
112 }
113
114 cfg_feature_alloc! {
115 fn reversed(&self) -> alloc::boxed::Box<[T]>
116 where
117 T: Copy + Default
118 {
119 let mut v : alloc::boxed::Box<[T]> = alloc::boxed::Box::from(self);
120 v.as_mut().reverse();
121 v
122 }
123 }
124}
125
126pub trait ArrayTools<T: Copy + Default, const N: usize> {
127 fn reversed(&self) -> [T; N];
128}
129impl<T: Copy + Default, const N: usize> ArrayTools<T, N> for [T; N] {
130 fn reversed(&self) -> [T; N] {
131 let mut c = *self;
132 c.reverse();
133 c
134 }
135}
136
137pub fn longest_consecutive_values<T: PartialOrd>(arr: &[T], val: &T) -> Option<(usize, usize)> {
149 let len = arr.len();
150 let mut best_count: usize = 0;
151 let mut best_position: usize = 0;
152 let mut start_pos = 0;
153 while start_pos < len {
154 let mut count: usize = 0;
155 let arr = arr.get(start_pos..)?;
156 for (idx, v) in arr.iter().enumerate() {
157 if v.ne(val) {
158 start_pos += idx;
159 break;
160 }
161 count += 1;
162 }
163 if count > best_count {
164 best_count = count;
165 if start_pos != 0 {
166 best_position = start_pos - count;
167 }
168 }
169 start_pos += 1;
170 }
171 if best_count > 0 {
172 return Some((best_position, best_count));
173 }
174 None
175}
176
177#[cfg(test)]
178mod tests {
179 use crate::arrays::longest_consecutive_values;
180
181 #[test]
182 pub fn test1() {
183 let (position, length) =
184 longest_consecutive_values(&[1, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6], &0).unwrap();
185
186 assert_eq!(position, 1);
187 assert_eq!(length, 5);
188 }
189
190 #[test]
191 pub fn test2() {
192 let (position, length) =
193 longest_consecutive_values(&[1, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 4, 5, 6], &0).unwrap();
194
195 assert_eq!(position, 6);
196 assert_eq!(length, 5);
197 }
198}