1
2use bitvec::vec::BitVec;
3use crate::error::BitMatrixError;
4
5type Result<T> = std::result::Result<T, BitMatrixError>;
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9pub struct BitMatrix {
10 pub width: usize,
12 pub height: usize,
14 bits: BitVec,
15}
16impl BitMatrix {
17 pub fn new() -> Self {
19 BitMatrix {
20 width: 0,
21 height: 0,
22 bits: BitVec::new(),
23 }
24 }
25 pub fn with_dimensions(width: usize, height: usize) -> Self {
27 let mut bits = BitVec::with_capacity(width*height);
28 bits.resize_with(width*height, Default::default);
29 BitMatrix {
30 width,
31 height,
32 bits,
33 }
34 }
35 pub fn from_bits(width: usize, height: usize, data: impl IntoIterator<Item=bool>) -> Self {
41 let mut bits: BitVec = data.into_iter().collect();
42 bits.resize_with(width*height, Default::default);
43 BitMatrix {
44 width,
45 height,
46 bits,
47 }
48 }
49 pub fn get(&self, x: usize, y: usize) -> Result<bool> {
51 if x >= self.width || y >= self.height {
52 return Err(BitMatrixError::OutOfBounds {
53 x_y: [x, y],
54 max_x_y: [self.width-1, self.height-1],
55 })
56 }
57 let index = y*self.width + x;
58 return match self.bits.get(index) {
59 Some(&bit) => Ok(bit),
60 None => Err(BitMatrixError::OutOfBounds {
61 x_y: [x, y],
62 max_x_y: [self.width-1, self.height-1],
63 }),
64 };
65 }
66 pub fn get_column(&self, x: usize) -> Result<Vec<bool>> {
70 if x >= self.width {
71 return Err(BitMatrixError::OutOfBounds {
72 x_y: [x, 0],
73 max_x_y: [self.width-1, self.height-1],
74 })
75 }
76 let mut column = Vec::new();
77 for row in 0..self.height {
78 column.push(self.bits[x + (row * self.width)]);
79 }
80 Ok(column)
81 }
82 pub fn get_row(&self, y: usize) -> Result<Vec<bool>> {
86 if y >= self.height {
87 return Err(BitMatrixError::OutOfBounds {
88 x_y: [0, y],
89 max_x_y: [self.width-1, self.height-1],
90 })
91 }
92 let mut row = Vec::new();
93 for column in 0..self.width {
94 row.push(self.bits[(y * self.width) + column]);
95 }
96 Ok(row)
97 }
98 pub fn set(&mut self, x: usize, y: usize, state: bool) -> Result<()> {
100 if x >= self.width || y >= self.height {
101 return Err(BitMatrixError::OutOfBounds {
102 x_y: [x, y],
103 max_x_y: [self.width-1, self.height-1],
104 })
105 }
106 let index: usize = y*self.width + x;
107 self.bits.set(index, state);
108 Ok(())
109 }
110 pub fn resize_width(&mut self, len: usize) {
115 if len > self.width {
119 let diff = len - self.width;
121 for row in (1..=self.height).rev() {
122 let row_end = self.width * row;
123 for _ in 0..diff { self.bits.insert(row_end, false); }
124 }
125 }
126 else if len < self.width {
127 let diff = self.width - len;
129 for row in (1..=self.height).rev() {
130 let row_end = self.width * row;
131 for _ in 0..diff { self.bits.remove(row_end-diff); }
132 }
133 }
134 self.width = len;
135 }
136 pub fn resize_height(&mut self, len: usize) {
141 if len > self.height {
142 let new_rows = len - self.height;
144 let new_bits = new_rows * self.width;
145 let end = self.bits.len();
146 for _ in 0..new_bits { self.bits.insert(end, false); }
147 }
148 else if len < self.height {
149 let less_rows = self.height - len;
151 let less_bits = less_rows * self.width;
152 let new_end = self.bits.len() - less_bits;
153 for _ in 0..less_bits { self.bits.remove(new_end); }
154 }
155 self.height = len;
156 }
157 pub fn to_bits(&self) -> Vec<bool> {
161 let mut bits = Vec::with_capacity(self.bits.len());
162 bits.extend(&self.bits);
163 bits
164 }
165 pub fn into_bits(self) -> Vec<bool> {
169 let mut bits = Vec::with_capacity(self.bits.len());
170 bits.extend(&self.bits);
171 bits
172 }
173 pub fn to_columns(&self) -> Vec<Vec<bool>> {
175 let mut vecs = vec![Vec::with_capacity(self.height); self.width];
176 for column in 0..self.width {
177 for row in 0..self.height {
178 vecs[column].push(self.bits[row*self.width + column]);
179 }
180 }
181 vecs
182 }
183 pub fn into_columns(self) -> Vec<Vec<bool>> {
185 let mut vecs = vec![Vec::with_capacity(self.height); self.width];
186 for column in 0..self.width {
187 for row in 0..self.height {
188 vecs[column].push(self.bits[row*self.width + column]);
189 }
190 }
191 vecs
192 }
193 pub fn to_rows(&self) -> Vec<Vec<bool>> {
195 let mut vecs = vec![Vec::with_capacity(self.width); self.height];
196 for row in 0..self.height {
197 vecs[row].extend(&self.bits[row*self.width..(row+1)*self.width]);
198 }
199 vecs
200 }
201 pub fn into_rows(self) -> Vec<Vec<bool>> {
203 let mut vecs = vec![Vec::with_capacity(self.width); self.height];
204 for row in 0..self.height {
205 vecs[row].extend(&self.bits[row*self.width..(row+1)*self.width]);
206 }
207 vecs
208 }
209 pub fn shrink_to_fit(&mut self) {
212 for col in (0..self.width).rev() {
216 let col_bits = {
217 let mut bv = BitVec::new();
218 bv.extend(self.get_column(col).unwrap());
219 bv
220 };
221 if !all_zeroes(&col_bits, 0, col_bits.len()) {
222 self.resize_width(col+1);
223 break
224 }
225 }
226 for row in (0..self.height).rev() {
227 let row_bits = {
228 let mut bv = BitVec::new();
229 bv.extend(self.get_row(row).unwrap());
230 bv
231 };
232 if !all_zeroes(&row_bits, 0, row_bits.len()) {
233 self.resize_height(row+1);
234 break
235 }
236 }
237 }
238}
239impl Default for BitMatrix {
240 fn default() -> Self {
241 BitMatrix::new()
242 }
243}
244
245fn all_zeroes(bits: &BitVec, begin: usize, end: usize) -> bool {
246 bits[begin..end].into_iter().fold(true, |total, bit| total & !bit)
247}
248
249#[cfg(test)]
250mod api {
251use super::*;
252 #[test]
253 fn new() {
254 let m = BitMatrix::new();
255 assert_eq!(0, m.width);
256 assert_eq!(0, m.height);
257 assert_eq!(Vec::<bool>::new(), m.into_bits());
258 }
259 #[test]
260 fn with_dimensions_0() {
261 let m = BitMatrix::with_dimensions(8, 8);
262 assert_eq!(8, m.width);
263 assert_eq!(8, m.height);
264 assert_eq!(vec![false; 64], m.into_bits());
265 }
266 #[test]
267 fn with_dimensions_1() {
268 let m = BitMatrix::with_dimensions(0, 0);
269 assert_eq!(0, m.width);
270 assert_eq!(0, m.height);
271 assert_eq!(vec![false; 0], m.to_bits());
272 assert_eq!(BitMatrix::new(), m);
273 }
274 #[test]
275 fn from_bit_0() {
276 let bits = vec![
277 false,false,false,true,
278 false,false,true,false,
279 false,true,false,false,
280 true,false,false,false,
281 ];
282 let m = BitMatrix::from_bits(4, 4, bits.clone());
283 assert_eq!(4, m.width);
284 assert_eq!(4, m.height);
285 assert_eq!(bits, m.into_bits());
286 }
287 #[test]
288 fn from_bits_1() {
289 let input_bits = vec![
290 false,false,false,true,
291 false,false,true,false,
292 false,true,false,false,
293 true,
294 ];
295 let expected_bits = vec![
296 false,false,false,true,
297 false,false,true,false,
298 false,true,false,false,
299 true,false,false,false,
300 ];
301 let m = BitMatrix::from_bits(4, 4, input_bits.clone());
302 assert_eq!(4, m.width);
303 assert_eq!(4, m.height);
304 assert_eq!(expected_bits, m.into_bits());
305 }
306 #[test]
307 fn from_bits_2() {
308 let input_bits = vec![
309 false,false,false,true,
310 false,false,true,false,
311 false,true,false,false,
312 true,false,false,false,true,true,false,false,true ];
314 let expected_bits = vec![
315 false,false,false,true,
316 false,false,true,false,
317 false,true,false,false,
318 true,false,false,false,
319 ];
320 let m = BitMatrix::from_bits(4, 4, input_bits.clone());
321 assert_eq!(4, m.width);
322 assert_eq!(4, m.height);
323 assert_eq!(expected_bits, m.into_bits());
324 }
325 #[test]
326 fn get() -> Result<()> {
327 let bits = vec![
328 false,false,false,true,
329 false,false,true,false,
330 false,true,false,false,
331 true,false,false,false,
332 ];
333 let m = BitMatrix::from_bits(4, 4, bits.clone());
334 assert_eq!(false, m.get(0, 0)?);
335 assert_eq!(false, m.get(0, 1)?);
336 assert_eq!(true, m.get(3, 0)?);
337 assert_eq!(true, m.get(2, 1)?);
338 assert_eq!(true, m.get(1, 2)?);
339 assert_eq!(true, m.get(0, 3)?);
340 assert_eq!(false, m.get(3, 3)?);
341 assert_eq!(BitMatrixError::OutOfBounds {
342 x_y: [4, 4],
343 max_x_y: [3, 3]
344 },
345 m.get(4, 4).unwrap_err()
346 );
347 Ok(())
348 }
349 #[test]
350 fn set() -> Result<()> {
351 let mut m = BitMatrix::with_dimensions(8, 8);
352 assert_eq!(false, m.get(0, 0)?);
353 m.set(0, 0, true)?;
354 assert_eq!(true, m.get(0, 0)?);
355 m.set(0, 0, false)?;
356 assert_eq!(false, m.get(0, 0)?);
357 m.set(3, 3, true)?;
358 assert_eq!(true, m.get(3, 3)?);
359 assert_eq!(false, m.get(2, 3)?);
360 assert_eq!(false, m.get(3, 2)?);
361 assert_eq!(BitMatrixError::OutOfBounds {
362 x_y: [8, 8],
363 max_x_y: [7, 7]
364 },
365 m.set(8, 8, true).unwrap_err()
366 );
367 Ok(())
368 }
369 #[test]
370 fn resize_width_grow() -> Result<()> {
371 let bits = vec![
372 false,false,false,true,
373 false,false,true,false,
374 false,true,false,false,
375 true,false,false,false,
376 ];
377 let mut m = BitMatrix::from_bits(4, 4, bits);
378 assert_eq!(4, m.width);
379 assert_eq!(true, m.get(3, 0)?);
380 assert!(m.get(7, 0).is_err());
381 m.resize_width(8);
382 assert_eq!(8, m.width);
383 assert_eq!(true, m.get(3, 0)?);
384 assert_eq!(false, m.get(4, 0)?);
385 assert_eq!(false, m.get(7, 0)?);
386 Ok(())
387 }
388 #[test]
389 fn resize_width_shrink() -> Result<()> {
390 let bits = vec![
391 false,false,false,true,
392 false,true,true,false,
393 false,true,false,false,
394 true,false,false,false,
395 ];
396 let mut m = BitMatrix::from_bits(4, 4, bits);
397 assert_eq!(4, m.width);
398 assert_eq!(true, m.get(3, 0)?);
399 assert_eq!(true, m.get(1, 2)?);
400 m.resize_width(2);
401 assert_eq!(2, m.width);
402 assert!(m.get(3, 0).is_err());
403 assert_eq!(false, m.get(1, 0)?);
404 assert_eq!(true, m.get(1, 1)?);
405 assert_eq!(BitMatrixError::OutOfBounds {
406 x_y: [2, 3],
407 max_x_y: [1, 3]
408 },
409 m.get(2, 3).unwrap_err()
410 );
411 Ok(())
412 }
413 #[test]
414 fn resize_height_grow() -> Result<()> {
415 let bits = vec![
416 false,false,false,true,
417 false,false,true,false,
418 false,true,false,false,
419 true,false,false,false,
420 ];
421 let mut m = BitMatrix::from_bits(4, 4, bits);
422 assert_eq!(4, m.height);
423 assert_eq!(true, m.get(0, 3)?);
424 assert!(m.get(0, 5).is_err());
425 m.resize_height(8);
426 assert_eq!(8, m.height);
427 assert_eq!(true, m.get(0, 3)?);
428 assert_eq!(false, m.get(0, 5)?);
429 Ok(())
430 }
431 #[test]
432 fn resize_height_shrink() -> Result<()> {
433 let bits = vec![
434 false,false,false,true,
435 false,true,true,false,
436 false,true,false,false,
437 true,false,false,false,
438 ];
439 let mut m = BitMatrix::from_bits(4, 4, bits);
440 assert_eq!(4, m.height);
441 assert_eq!(true, m.get(0, 3)?);
442 assert_eq!(false, m.get(0, 1)?);
443 m.resize_height(2);
444 assert_eq!(2, m.height);
445 assert!(m.get(0, 3).is_err());
446 assert_eq!(false, m.get(0, 1)?);
447 assert_eq!(true, m.get(1, 1)?);
448 assert_eq!(BitMatrixError::OutOfBounds {
449 x_y: [3, 2],
450 max_x_y: [3, 1]
451 },
452 m.get(3, 2).unwrap_err()
453 );
454 Ok(())
455 }
456 #[test]
457 fn to_bits() {
458 let bits = vec![
459 false,false,false,true,
460 false,false,true,false,
461 false,true,false,false,
462 true,false,false,false,
463 ];
464 assert_eq!(bits, BitMatrix::from_bits(4, 4, bits.clone()).to_bits());
465 }
466 #[test]
467 fn into_bits() {
468 let bits = vec![
469 false,false,false,true,
470 false,false,true,false,
471 false,true,false,false,
472 true,false,false,false,
473 ];
474 assert_eq!(bits, BitMatrix::from_bits(4, 4, bits.clone()).into_bits());
475 }
476 #[test]
477 fn to_columns() {
478 let bits = vec![
479 false,false,false,true,
480 false,false,true,false,
481 false,true,false,false,
482 true,false,false,false,
483 ];
484 let vecs = BitMatrix::from_bits(4, 4, bits.clone()).to_columns();
485 assert_eq!(4, vecs.len());
486 for column in 0..4 { assert_eq!(4, vecs[column].len()); }
487 assert_eq!(vec![bits[0], bits[4], bits[8], bits[12]], vecs[0]);
488 assert_eq!(vec![bits[1], bits[5], bits[9], bits[13]], vecs[1]);
489 assert_eq!(vec![bits[2], bits[6], bits[10], bits[14]], vecs[2]);
490 assert_eq!(vec![bits[3], bits[7], bits[11], bits[15]], vecs[3]);
491 }
492 #[test]
493 fn into_columns() {
494 let bits = vec![
495 false,false,false,true,
496 false,false,true,false,
497 false,true,false,false,
498 true,false,false,false,
499 ];
500 let vecs = BitMatrix::from_bits(4, 4, bits.clone()).into_columns();
501 assert_eq!(4, vecs.len());
502 for column in 0..4 { assert_eq!(4, vecs[column].len()); }
503 assert_eq!(vec![bits[0], bits[4], bits[8], bits[12]], vecs[0]);
504 assert_eq!(vec![bits[1], bits[5], bits[9], bits[13]], vecs[1]);
505 assert_eq!(vec![bits[2], bits[6], bits[10], bits[14]], vecs[2]);
506 assert_eq!(vec![bits[3], bits[7], bits[11], bits[15]], vecs[3]);
507 }
508 #[test]
509 fn to_rows() {
510 let bits = vec![
511 false,false,false,true,
512 false,false,true,false,
513 false,true,false,false,
514 true,false,false,false,
515 ];
516 let rows = BitMatrix::from_bits(4, 4, bits.clone()).to_rows();
517 assert_eq!(4, rows.len());
518 for row in 0..4 { assert_eq!(4, rows[row].len()); }
519 assert_eq!(bits[0..4].to_vec(), rows[0]);
520 assert_eq!(bits[4..8].to_vec(), rows[1]);
521 assert_eq!(bits[8..12].to_vec(), rows[2]);
522 assert_eq!(bits[12..16].to_vec(), rows[3]);
523 }
524 #[test]
525 fn into_rows() {
526 let bits = vec![
527 false,false,false,true,
528 false,false,true,false,
529 false,true,false,false,
530 true,false,false,false,
531 ];
532 let rows = BitMatrix::from_bits(4, 4, bits.clone()).into_rows();
533 assert_eq!(4, rows.len());
534 for row in 0..4 { assert_eq!(4, rows[row].len()); }
535 assert_eq!(bits[0..4].to_vec(), rows[0]);
536 assert_eq!(bits[4..8].to_vec(), rows[1]);
537 assert_eq!(bits[8..12].to_vec(), rows[2]);
538 assert_eq!(bits[12..16].to_vec(), rows[3]);
539 }
540 #[test]
541 fn get_column() -> Result<()> {
542 let bits = vec![
543 false,false,false,true,
544 false,false,true,false,
545 false,true,false,false,
546 true,false,false,false,
547 ];
548 let m = BitMatrix::from_bits(4, 4, bits.clone());
549 assert_eq!(
550 vec![false,false,false,true],
551 m.get_column(0)?
552 );
553 assert_eq!(
554 vec![false,false,true,false],
555 m.get_column(1)?
556 );
557 assert_eq!(
558 vec![false,true,false,false],
559 m.get_column(2)?
560 );
561 assert_eq!(
562 vec![true,false,false,false],
563 m.get_column(3)?
564 );
565 Ok(())
566 }
567 #[test]
568 fn get_row() -> Result<()> {
569 let bits = vec![
570 false,false,false,true,
571 false,false,true,false,
572 false,true,false,false,
573 true,false,false,false,
574 ];
575 let m = BitMatrix::from_bits(4, 4, bits.clone());
576 assert_eq!(
577 vec![false,false,false,true],
578 m.get_row(0)?
579 );
580 assert_eq!(
581 vec![false,false,true,false],
582 m.get_row(1)?
583 );
584 assert_eq!(
585 vec![false,true,false,false],
586 m.get_row(2)?
587 );
588 assert_eq!(
589 vec![true,false,false,false],
590 m.get_row(3)?
591 );
592 Ok(())
593 }
594 #[test]
595 fn shrink_to_fit() {
596 let bits = vec![
597 true,true,false,false,
598 true,false,true,false,
599 false,false,false,false,
600 false,false,false,false,
601 ];
602 let mut m = BitMatrix::from_bits(4, 4, bits.clone());
603 assert_eq!(4, m.width);
604 assert_eq!(4, m.height);
605 m.shrink_to_fit();
606 assert_eq!(3, m.width);
607 assert_eq!(2, m.height);
608 }
609}