1use std::ops::RangeFull;
2
3use monoid::Monoid;
4
5#[derive(Clone, Eq, PartialEq)]
6pub struct FoldableDeque<M: Monoid> {
7 front: Vec<M::Set>,
8 front_folded: Vec<M::Set>,
9 back: Vec<M::Set>,
10 back_folded: Vec<M::Set>,
11 monoid: M,
12}
13
14impl<M: Monoid> FoldableDeque<M>
15where
16 M::Set: Clone,
17{
18 pub fn new() -> Self
19 where
20 M: Default,
21 {
22 let monoid = M::default();
23 Self {
24 front: vec![],
25 front_folded: vec![monoid.id()],
26 back: vec![],
27 back_folded: vec![monoid.id()],
28 monoid,
29 }
30 }
31 pub fn push_back(&mut self, elt: M::Set) {
32 let tmp = self.monoid.op(self.back_folded.last().unwrap(), &elt);
33 self.back_folded.push(tmp);
34 self.back.push(elt);
35 }
36 pub fn push_front(&mut self, elt: M::Set) {
37 let tmp = self.monoid.op(&elt, self.front_folded.last().unwrap());
38 self.front_folded.push(tmp);
39 self.front.push(elt);
40 }
41 pub fn pop_back(&mut self) -> Option<M::Set> {
42 self.rotate_back();
43 let elt = self.back.pop()?;
44 self.back_folded.pop().unwrap();
45 Some(elt)
46 }
47 pub fn pop_front(&mut self) -> Option<M::Set> {
48 self.rotate_front();
49 let elt = self.front.pop()?;
50 self.front_folded.pop().unwrap();
51 Some(elt)
52 }
53 pub fn fold(&self, _: RangeFull) -> M::Set {
54 self.monoid.op(
55 self.front_folded.last().unwrap(),
56 self.back_folded.last().unwrap(),
57 )
58 }
59
60 fn rotate_front(&mut self) {
61 if !self.front.is_empty() {
62 return;
63 }
64 let mut front = std::mem::take(&mut self.back);
65 let len = front.len();
66
67 let back = front.split_off((len + 1) / 2);
70 front.reverse();
71 self.front = front;
72 self.back = back;
73 self.fixup();
74 }
75 fn rotate_back(&mut self) {
76 if !self.back.is_empty() {
77 return;
78 }
79 let mut back = std::mem::take(&mut self.front);
80 let len = back.len();
81
82 let front = back.split_off((len + 1) / 2);
85 back.reverse();
86 self.front = front;
87 self.back = back;
88 self.fixup();
89 }
90 fn fixup(&mut self) {
91 self.front_folded = vec![self.monoid.id()];
92 self.front_folded.extend(self.front.iter().scan(
93 self.monoid.id(),
94 |acc, x| {
95 *acc = self.monoid.op(x, acc);
96 Some(acc.clone())
97 },
98 ));
99
100 self.back_folded = vec![self.monoid.id()];
101 self.back_folded.extend(self.back.iter().scan(
102 self.monoid.id(),
103 |acc, x| {
104 *acc = self.monoid.op(acc, x);
105 Some(acc.clone())
106 },
107 ));
108 }
109}
110
111impl<M: Monoid> std::fmt::Debug for FoldableDeque<M>
112where
113 M::Set: std::fmt::Debug,
114{
115 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116 f.debug_list()
117 .entries(self.front.iter().rev().chain(self.back.iter()))
118 .finish()
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use concat_monoid::OpConcat;
125
126 use crate::FoldableDeque;
127
128 #[test]
129 fn sanity_check() {
130 let mut queue = FoldableDeque::<OpConcat<_, Vec<_>>>::new();
131 queue.push_back(vec![1]);
132 assert_eq!(queue.fold(..), vec![1]);
133 assert_eq!(queue.pop_back(), Some(vec![1]));
134
135 queue.push_back(vec![1]);
136 queue.push_back(vec![2]);
137 queue.push_back(vec![3]);
138 queue.push_back(vec![4]);
139 queue.push_back(vec![5]);
140 assert_eq!(queue.fold(..), vec![1, 2, 3, 4, 5]);
141
142 assert_eq!(queue.pop_front(), Some(vec![1]));
143 assert_eq!(queue.fold(..), vec![2, 3, 4, 5]);
144 assert_eq!(queue.pop_front(), Some(vec![2]));
145 assert_eq!(queue.fold(..), vec![3, 4, 5]);
146 assert_eq!(queue.pop_front(), Some(vec![3]));
147 assert_eq!(queue.fold(..), vec![4, 5]);
148 assert_eq!(queue.pop_front(), Some(vec![4]));
149 assert_eq!(queue.fold(..), vec![5]);
150 assert_eq!(queue.pop_front(), Some(vec![5]));
151 assert_eq!(queue.fold(..), vec![]);
152 assert_eq!(queue.pop_front(), None);
153 assert_eq!(queue.fold(..), vec![]);
154
155 queue.push_front(vec![5]);
156 queue.push_front(vec![4]);
157 queue.push_front(vec![3]);
158 queue.push_front(vec![2]);
159 queue.push_front(vec![1]);
160 assert_eq!(queue.fold(..), vec![1, 2, 3, 4, 5]);
161
162 assert_eq!(queue.pop_back(), Some(vec![5]));
163 assert_eq!(queue.fold(..), vec![1, 2, 3, 4]);
164 assert_eq!(queue.pop_back(), Some(vec![4]));
165 assert_eq!(queue.fold(..), vec![1, 2, 3]);
166 assert_eq!(queue.pop_back(), Some(vec![3]));
167 assert_eq!(queue.fold(..), vec![1, 2]);
168 assert_eq!(queue.pop_back(), Some(vec![2]));
169 assert_eq!(queue.fold(..), vec![1]);
170 assert_eq!(queue.pop_back(), Some(vec![1]));
171 assert_eq!(queue.fold(..), vec![]);
172 assert_eq!(queue.pop_back(), None);
173 assert_eq!(queue.fold(..), vec![]);
174 }
175
176 #[test]
177 fn test_fmt() {
178 let mut queue = FoldableDeque::<OpConcat<_, Vec<_>>>::new();
179 assert_eq!(format!("{queue:?}"), "[]");
180 queue.push_front(vec![2]);
181 queue.push_front(vec![1]);
182 queue.push_back(vec![3]);
183 queue.push_back(vec![4]);
184 assert_eq!(format!("{queue:?}"), "[[1], [2], [3], [4]]");
185 }
186}