1. /// Calculate the differences between elements of `values` offset by `offset`,
2. /// wrapping around from the end of `values` to the beginning.
3. ///
4. /// Element `n` of the result is `values[(n+offset)%len] - values[n]`.
5. fn offset_differences<N>(offset: usize, values: Vec<N>) -> Vec<N>
6. where
7. N: Copy + std::ops::Sub<Output = N>,
8. {
9. let a = (&values).into_iter();
10. let b = (&values).into_iter().cycle().skip(offset);
11. a.zip(b).map(|(a, b)| *b - *a).collect()
12. }
14. #[test]
15. fn test_offset_one() {
16. assert_eq!(offset_differences(1, vec![1, 3, 5, 7]), vec![2, 2, 2, -6]);
17. assert_eq!(offset_differences(1, vec![1, 3, 5]), vec![2, 2, -4]);
18. assert_eq!(offset_differences(1, vec![1, 3]), vec![2, -2]);
19. }
21. #[test]
22. fn test_larger_offsets() {
23. assert_eq!(offset_differences(2, vec![1, 3, 5, 7]), vec![4, 4, -4, -4]);
24. assert_eq!(offset_differences(3, vec![1, 3, 5, 7]), vec![6, -2, -2, -2]);
25. assert_eq!(offset_differences(4, vec![1, 3, 5, 7]), vec![0, 0, 0, 0]);
26. assert_eq!(offset_differences(5, vec![1, 3, 5, 7]), vec![2, 2, 2, -6]);
27. }
29. #[test]
30. fn test_custom_type() {
31. assert_eq!(
32. offset_differences(1, vec![1.0, 11.0, 5.0, 0.0]),
33. vec![10.0, -6.0, -5.0, 1.0]
34. );
35. }
37. #[test]
38. fn test_degenerate_cases() {
39. assert_eq!(offset_differences(1, vec![0]), vec![0]);
40. assert_eq!(offset_differences(1, vec![1]), vec![0]);
41. let empty: Vec<i32> = vec![];
42. assert_eq!(offset_differences(1, empty), vec![]);
43. }
45. fn main() {}