diff --git a/src/lib.rs b/src/lib.rs index ca91a67..5635ce9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,6 +26,12 @@ pub struct Adjacencies { } impl Adjacencies { + pub fn for_table(seats: &Seating) -> Self { + let mut adj = Self::new(seats.amount); + seats.get_adjacent(&mut adj); + adj + } + pub fn new(size: usize) -> Self { Adjacencies { amap: (0..size).map(|_| BitVec::from_elem(size, false)).collect(), @@ -43,7 +49,7 @@ impl Adjacencies { fn is_disjoint(&mut self, other: &Adjacencies) -> bool { self.amap.iter_mut().enumerate().all(|(key, bitvec)| { bitvec.and(&other.amap[key]); - !bitvec.any() + bitvec.none() }) } @@ -61,6 +67,21 @@ impl Adjacencies { .collect(), } } + + pub fn union(&self, other: &Adjacencies) -> Adjacencies { + Adjacencies { + amap: self + .amap + .iter() + .enumerate() + .map(|(key, bitset)| { + let mut bc = bitset.clone(); + bc.or(&other.amap[key]); + bc + }) + .collect(), + } + } } impl Display for Adjacencies { @@ -104,12 +125,10 @@ impl Display for Seating { impl Seating { pub fn calc_alternatives( - &self, size: usize, + old_adjacencies: &Adjacencies, ) -> impl Coroutine { - let mut old_adjacencies = Adjacencies::new(size); - self.get_adjacent(&mut old_adjacencies); - + let old_adjacencies = old_adjacencies.clone(); #[coroutine] move || { let mut checked_locations = 0; @@ -197,7 +216,7 @@ impl Seating { side[x] = Some(person); } - fn get_adjacent(&self, prev_adj: &mut Adjacencies) { + pub fn get_adjacent(&self, prev_adj: &mut Adjacencies) { for (i, person) in self.people_top.iter().enumerate() { if let &Some(person) = person { assert!( diff --git a/src/main.rs b/src/main.rs index 8137114..d9c7cab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,26 +1,43 @@ #![feature(coroutine_trait)] use std::{ + fs::File, + io::{BufWriter, Result, Write}, ops::{Coroutine, CoroutineState}, pin::Pin, + time::Instant, }; use shuffles::*; -fn main() { +fn main() -> Result<()> { + // let file = File::create("./valid_seatings")?; + // let mut bf = BufWriter::new(file); + for size in 0..18 { let table = Seating::make_seating(size); println!("We have a table\n{table}"); - let mut corot = table.calc_alternatives(size); + let mut old_adjacencies = Adjacencies::for_table(&table); + let mut corot = Seating::calc_alternatives(size, &old_adjacencies); println!("searching size {size}"); + let mut total = 0; + let start = Instant::now(); loop { match Pin::new(&mut corot).resume(()) { - CoroutineState::Yielded(_val) => total += 1, + CoroutineState::Yielded(val) => { + // writeln!(bf, "Seating {} for size {} is \n{}", total, size, val)?; + total += 1; + } CoroutineState::Complete(total_checked) => { println!("checked {total_checked} in total to find {total} valid alternatives"); break; } } } + println!( + "finished size {size} in {:.03} sec", + start.elapsed().as_secs_f64() + ) } + Ok(()) }