haar_lib/algebra/
max_contiguous.rs1use crate::algebra::traits::*;
7use crate::impl_algebra;
8
9#[derive(Clone, Debug, PartialEq, Eq)]
11pub struct MaxContiguous<T> {
12 pub max: (usize, T),
14 pub left: (usize, T),
16 pub right: (usize, T),
18 pub length: usize,
20}
21
22impl<T: Copy> MaxContiguous<T> {
23 pub fn unit(value: T) -> Self {
25 Self {
26 max: (1, value),
27 left: (1, value),
28 right: (1, value),
29 length: 1,
30 }
31 }
32}
33
34fn max<T>(a: (usize, T), b: (usize, T)) -> (usize, T) {
35 if a.0 >= b.0 {
36 a
37 } else {
38 b
39 }
40}
41
42fn join<T: Eq>(a: (usize, T), b: (usize, T)) -> (usize, T) {
43 if a.1 == b.1 {
44 (a.0 + b.0, a.1)
45 } else {
46 max(a, b)
47 }
48}
49
50impl<T: Copy + Eq> BinaryOp for MaxContiguous<T> {
51 fn op(self, other: Self) -> Self {
52 let (a, b) = (self, other);
53
54 let max = max(max(a.max, b.max), join(a.right, b.left));
55
56 let left = if a.left.0 == a.length && a.left.1 == b.left.1 {
57 (a.left.0 + b.left.0, a.left.1)
58 } else {
59 a.left
60 };
61
62 let right = if b.right.0 == b.length && a.right.1 == b.right.1 {
63 (a.right.0 + b.right.0, b.right.1)
64 } else {
65 b.right
66 };
67
68 let length = a.length + b.length;
69
70 Self {
71 max,
72 left,
73 right,
74 length,
75 }
76 }
77}
78
79impl_algebra!(
80 [T: Copy + Eq]; MaxContiguous<T>;
81 assoc;
82);