1#[macro_export]
10macro_rules! array {
11 (@accum (0, $($_es:expr),*) -> ($($body:tt)*))
12 => {array!(@as_expr [$($body)*])};
13 (@accum (1, $($es:expr),*) -> ($($body:tt)*))
14 => {array!(@accum (0, $($es),*) -> ($($body)* $($es,)*))};
15 (@accum (2, $($es:expr),*) -> ($($body:tt)*))
16 => {array!(@accum (0, $($es),*) -> ($($body)* $($es,)* $($es,)*))};
17 (@accum (3, $($es:expr),*) -> ($($body:tt)*))
18 => {array!(@accum (2, $($es),*) -> ($($body)* $($es,)*))};
19 (@accum (4, $($es:expr),*) -> ($($body:tt)*))
20 => {array!(@accum (2, $($es,)* $($es),*) -> ($($body)*))};
21 (@accum (5, $($es:expr),*) -> ($($body:tt)*))
22 => {array!(@accum (4, $($es),*) -> ($($body)* $($es,)*))};
23 (@accum (6, $($es:expr),*) -> ($($body:tt)*))
24 => {array!(@accum (4, $($es),*) -> ($($body)* $($es,)* $($es,)*))};
25 (@accum (7, $($es:expr),*) -> ($($body:tt)*))
26 => {array!(@accum (4, $($es),*) -> ($($body)* $($es,)* $($es,)* $($es,)*))};
27 (@accum (8, $($es:expr),*) -> ($($body:tt)*))
28 => {array!(@accum (4, $($es,)* $($es),*) -> ($($body)*))};
29 (@accum (16, $($es:expr),*) -> ($($body:tt)*))
30 => {array!(@accum (8, $($es,)* $($es),*) -> ($($body)*))};
31 (@accum (32, $($es:expr),*) -> ($($body:tt)*))
32 => {array!(@accum (16, $($es,)* $($es),*) -> ($($body)*))};
33 (@accum (64, $($es:expr),*) -> ($($body:tt)*))
34 => {array!(@accum (32, $($es,)* $($es),*) -> ($($body)*))};
35
36 (@as_expr $e:expr) => {$e};
37
38 [$e:expr; $n:tt] => { array!(@accum ($n, $e) -> ()) };
39}
40
41pub fn max_index<T: PartialOrd>(arr: &[T]) -> Option<usize> {
54 let mut max_idx: Option<usize> = None;
55 let mut max_val: Option<&T> = None;
56 for (idx, val) in arr.iter().enumerate() {
57 if max_idx.is_none() {
58 max_idx = Some(idx);
59 max_val = Some(val);
60 } else if let Some(mv) = max_val {
61 if val.gt(mv) {
62 max_val = Some(val);
63 max_idx = Some(idx);
64 }
65 }
66 }
67 max_idx
68}
69
70pub fn copy_subset<T: Copy + Default, const N: usize>(arr: &[T]) -> [T; N] {
74 let mut out = [T::default(); N];
75 out.copy_from_slice(arr.split_at(N).0);
76 out
77}
78
79pub fn longest_consecutive_values<T: PartialOrd>(arr: &[T], val: &T) -> Option<(usize, usize)> {
91 let len = arr.len();
92 let mut best_count: usize = 0;
93 let mut best_position: usize = 0;
94 let mut start_pos = 0;
95 while start_pos < len {
96 let mut count: usize = 0;
97 let arr = arr.get(start_pos..)?;
98 for (idx, v) in arr.iter().enumerate() {
99 if v.ne(val) {
100 start_pos += idx;
101 break;
102 }
103 count += 1;
104 }
105 if count > best_count {
106 best_count = count;
107 if start_pos != 0 {
108 best_position = start_pos - count;
109 }
110 }
111 start_pos += 1;
112 }
113 if best_count > 0 {
114 return Some((best_position, best_count));
115 }
116 None
117}
118
119#[cfg(test)]
120mod tests {
121 use crate::arrays::longest_consecutive_values;
122
123 #[test]
124 pub fn test1() {
125 let (position, length) =
126 longest_consecutive_values(&[1, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6], &0).unwrap();
127
128 assert_eq!(position, 1);
129 assert_eq!(length, 5);
130 }
131
132 #[test]
133 pub fn test2() {
134 let (position, length) =
135 longest_consecutive_values(&[1, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 4, 5, 6], &0).unwrap();
136
137 assert_eq!(position, 6);
138 assert_eq!(length, 5);
139 }
140}