helpers.rs
1 // Copyright (c) 2025 ADnet Contributors 2 // This file is part of the AlphaOS library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 /// Generates a string containing all continuous sequenences within the list of numbers. 17 /// 18 /// The function expects the input to already be sorted. 19 pub fn rangify_heights(heights: &[u32]) -> String { 20 let mut iter = heights.iter().copied().peekable(); 21 let mut ret = String::from("["); 22 let mut first = true; 23 24 while let Some(next_height) = iter.next() { 25 let start = next_height; 26 let mut curr_height = start; 27 28 while let Some(next_height) = iter.peek().copied() { 29 if next_height == curr_height + 1 { 30 curr_height += 1; 31 let _ = iter.next(); 32 } else { 33 break; 34 } 35 } 36 37 if first { 38 first = false; 39 } else { 40 ret.push_str(", "); 41 } 42 43 if curr_height == start { 44 ret.push_str(&format!("{curr_height}")); 45 } else { 46 ret.push_str(&format!("{start}-{curr_height}")); 47 } 48 } 49 50 ret.push(']'); 51 ret 52 } 53 54 #[cfg(test)] 55 mod tests { 56 use super::rangify_heights; 57 58 #[test] 59 fn test_rangify_heights_empty() { 60 let heights = &[]; 61 62 let rangified = rangify_heights(heights); 63 assert_eq!(rangified, "[]"); 64 } 65 66 #[test] 67 fn test_rangify_heights_single_value() { 68 let heights = &[52425]; 69 70 let rangified = rangify_heights(heights); 71 assert_eq!(rangified, "[52425]"); 72 } 73 74 #[test] 75 fn test_rangify_large_continuous() { 76 let start = 16353; 77 let end = start + 52414; 78 79 let heights: Vec<u32> = (start..=end).collect(); 80 81 let rangified = rangify_heights(&heights); 82 assert_eq!(rangified, format!("[{start}-{end}]")); 83 } 84 85 #[test] 86 fn test_rangify_many_small() { 87 let mut heights = vec![]; 88 let mut expected = vec![]; 89 90 for idx in 0..100 { 91 let start = idx * 4; 92 let mid = idx * 4 + 1; 93 let end = idx * 4 + 2; 94 expected.push(format!("{start}-{end}")); 95 heights.push(start); 96 heights.push(mid); 97 heights.push(end); 98 } 99 100 let rangified = rangify_heights(&heights); 101 let expected = format!("[{}]", expected.join(", ")); 102 103 assert_eq!(rangified, expected); 104 } 105 106 #[test] 107 fn test_rangify_heights_multiple_ranges() { 108 let heights = &[0, 1, 3, 4, 5, 6, 7, 10, 11, 12, 20, 22, 23, 24, 25, 27, 28]; 109 110 let rangified = rangify_heights(heights); 111 assert_eq!(rangified, "[0-1, 3-7, 10-12, 20, 22-25, 27-28]"); 112 } 113 }