1use std::cmp::Reverse;
2use std::collections::BinaryHeap;
3
4#[derive(Default)]
5pub struct StreamingUnsignedMedian {
6 lo: BinaryHeap<u128>, hi: BinaryHeap<Reverse<u128>>, }
9
10impl StreamingUnsignedMedian {
11 pub fn insert<V: Into<u128>>(&mut self, v: V) {
12 let v = v.into();
13 self.hi.push(Reverse(v));
15 if let Some(Reverse(v)) = self.hi.pop() {
16 self.lo.push(v);
17 }
18 if self.lo.len() > self.hi.len() + 1 {
20 let v = self.lo.pop().unwrap();
21 self.hi.push(Reverse(v));
22 }
23 }
24
25 pub fn get_median(&self) -> u128 {
26 self.get_median_checked()
27 .expect("should check first with `median_checked`")
28 }
29
30 pub fn get_median_checked(&self) -> Option<u128> {
31 if self.lo.is_empty() {
32 return None;
33 }
34 if self.lo.len() > self.hi.len() {
35 Some(*self.lo.peek().unwrap())
36 } else {
37 let a = *self.lo.peek().unwrap();
38 let b = self.hi.peek().unwrap().0;
39 Some(a.saturating_add(b).saturating_div(2))
40 }
41 }
42}
43
44pub struct VecOfStreamingUnsignedMedian {
45 idx: usize,
46 inner: Vec<StreamingUnsignedMedian>,
47}
48
49impl VecOfStreamingUnsignedMedian {
50 pub fn new(capacity: usize) -> Self {
51 let mut vec = Vec::with_capacity(capacity);
52 for _ in 0..capacity {
53 vec.push(StreamingUnsignedMedian::default());
54 }
55 Self { idx: 0, inner: vec }
56 }
57
58 pub fn accum<V: Into<u128>>(&mut self, idx: usize, v: V) {
59 self.insert(idx, v);
60 }
61
62 pub fn accum_next<V: Into<u128>>(&mut self, v: V) {
63 self.insert_next(v);
64 }
65
66 pub fn insert<V: Into<u128>>(&mut self, idx: usize, v: V) {
67 self.idx = idx;
68 self.insert_curr(v);
69 }
70
71 pub fn insert_next<V: Into<u128>>(&mut self, v: V) {
72 self.idx += 1;
73 self.insert_curr(v);
74 }
75
76 fn insert_curr<V: Into<u128>>(&mut self, v: V) {
77 self.inner[self.idx].insert(v);
78 }
79
80 pub fn get_avg(&mut self, idx: usize) -> u128 {
81 self.get_median(idx)
82 }
83
84 pub fn get_avg_checked(&mut self, idx: usize) -> Option<u128> {
85 self.get_median_checked(idx)
86 }
87
88 pub fn get_avg_next(&mut self) -> u128 {
89 self.get_median_next()
90 }
91
92 pub fn get_avg_next_checked(&mut self) -> Option<u128> {
93 self.get_median_next_checked()
94 }
95
96 pub fn get_median(&mut self, idx: usize) -> u128 {
97 self.get_median_checked(idx)
98 .expect("should check first with `get_median_checked`")
99 }
100
101 pub fn get_median_checked(&mut self, idx: usize) -> Option<u128> {
102 self.idx = idx;
103 self.get_median_curr()
104 }
105
106 pub fn get_median_next(&mut self) -> u128 {
107 self.get_median_next_checked()
108 .expect("should check first with `get_median_checked`")
109 }
110
111 pub fn get_median_next_checked(&mut self) -> Option<u128> {
112 self.idx += 1;
113 self.get_median_curr()
114 }
115
116 fn get_median_curr(&self) -> Option<u128> {
117 self.inner[self.idx].get_median_checked()
118 }
119}