123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- // Use bitfields instead of HashSets.
- /*
- Or MAYBE, just use Vec<bool> ?!
- While that would use more memory, it would certainly be faster!
- Is saving a few bytes (these days) worth it, really?
- The iterator would be interesting...
- And we could handle any crazy size as well... :O
- */
- use bit_field::BitField;
- // If I wanted to do 4x4 or 5x5, I would need more bits. (u32).
- use num::Integer;
- use std::ops::RangeBounds;
- use std::fmt;
- #[derive(Copy, Clone, PartialEq)]
- pub struct GenBits<T: Integer + BitField>(pub T);
- impl<T: Integer + BitField> GenBits<T> {
- pub fn clear(&mut self) {
- self.0 = T::zero();
- }
- pub fn set(&mut self, bit: usize, value: bool) {
- self.0.set_bit(bit, value);
- }
- #[must_use]
- pub fn get(&self, bit: usize) -> bool {
- self.0.get_bit(bit)
- }
- pub fn set_bits<R: RangeBounds<u8> + IntoIterator<Item = u8>>(&mut self, bits: R) {
- for i in bits {
- self.set(i as usize, true);
- }
- }
- #[must_use]
- pub fn count_set(&self) -> u8 {
- let mut count: u8 = 0;
- for i in 0..T::BIT_LENGTH {
- if self.get(i) {
- count += 1;
- }
- }
- count
- }
- /// Display bits that are set.
- /// +1 is added to the display, so it matches the cell values (1..N)
- pub fn display(&self) -> String {
- self.iter()
- .map(|i| (i+1).to_string())
- // .map(|i| i.to_string())
- .collect::<Vec<_>>().join(",")
- }
- }
- impl<T: Integer + BitField + ToString> fmt::Debug for GenBits<T> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let result = self.iter()
- // .map(|i| (i+1).to_string())
- .map(|i| i.to_string())
- .collect::<Vec<_>>().join(",");
- if result.is_empty() {
- return write!(f, "{{}}")
- } else {
- return write!(f, "<{}>", result)
- }
- }
- }
- pub struct GenBitsIterator<'a, T: Integer + BitField> {
- pub possible: &'a GenBits<T>,
- pub index: usize,
- }
- impl<T: Integer + BitField> GenBits<T> {
- pub fn iter(&self) -> GenBitsIterator<T> {
- GenBitsIterator {
- possible: self,
- index: 0,
- }
- }
- }
- impl<'a, T: Integer + BitField> Iterator for GenBitsIterator<'a, T> {
- type Item = u8;
- fn next(&mut self) -> Option<u8> {
- while (self.index < T::BIT_LENGTH) && (!self.possible.get(self.index as usize)) {
- self.index += 1;
- }
- if self.index == T::BIT_LENGTH {
- None
- } else {
- self.index += 1;
- Some((self.index - 1) as u8)
- }
- }
- }
- #[cfg(test)]
- mod tests {
- // use crate::sudoku::*;
- use crate::bits::*;
- #[test]
- fn check_u16() {
- let mut p = GenBits::<u16>(0);
- p.clear();
- for i in 0..9 {
- let mut result = p.get(i);
- assert_eq!(result, false);
- p.set(i, true);
- result = p.get(i);
- assert_eq!(result, true);
- }
- p = GenBits::<u16>(0);
- p.set(3, true);
- p.set(5, true);
- p.set(6, true);
- assert_eq!(3, p.count_set());
- let values: Vec<u8> = p.iter().collect();
- assert_eq!(values, vec!(3, 5, 6));
- assert_eq!(3, p.count_set());
- p.set(0, true);
- assert_eq!(4, p.count_set());
- p = GenBits::<u16>(0);
- p.set_bits(0..6);
- for i in 0..6 {
- let result = p.get(i);
- assert_eq!(result, true);
- }
- assert_eq!(p.get(6), false);
- }
- #[test]
- fn check_u32() {
- let mut p = GenBits::<u32>(0);
- p.clear();
- for i in 0..29 {
- let mut result = p.get(i);
- assert_eq!(result, false);
- p.set(i, true);
- result = p.get(i);
- assert_eq!(result, true);
- }
- p = GenBits::<u32>(0);
- p.set(13, true);
- p.set(15, true);
- p.set(26, true);
- assert_eq!(3, p.count_set());
- let values: Vec<u8> = p.iter().collect();
- assert_eq!(values, vec!(13, 15, 26));
- assert_eq!(3, p.count_set());
- p.set(0, true);
- assert_eq!(4, p.count_set());
- p = GenBits::<u32>(0);
- p.set_bits(10..26);
- for i in 10..26 {
- let result = p.get(i);
- assert_eq!(result, true);
- }
- assert_eq!(p.get(9), false);
- assert_eq!(p.get(27), false);
- }
- }
|